Merge "Dismiss recents after switching users" into oc-mr1-dev
diff --git a/Android.mk b/Android.mk
index 69c8c2c..19bbc5f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -172,6 +172,7 @@
core/java/android/content/pm/IPackageInstallerCallback.aidl \
core/java/android/content/pm/IPackageInstallerSession.aidl \
core/java/android/content/pm/IPackageManager.aidl \
+ ../native/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl \
core/java/android/content/pm/IPackageMoveObserver.aidl \
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/content/pm/IPinItemRequest.aidl \
@@ -269,6 +270,8 @@
core/java/android/os/IRecoverySystemProgressListener.aidl \
core/java/android/os/IRemoteCallback.aidl \
core/java/android/os/ISchedulingPolicyService.aidl \
+ core/java/android/os/IThermalEventListener.aidl \
+ core/java/android/os/IThermalService.aidl \
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
@@ -1013,8 +1016,8 @@
-since $(SRC_API_DIR)/23.txt 23 \
-since $(SRC_API_DIR)/24.txt 24 \
-since $(SRC_API_DIR)/25.txt 25 \
- -since ./frameworks/base/api/current.txt O \
- -werror -hide 111 -hide 113 -hide 121 \
+ -since $(SRC_API_DIR)/26.txt 26 \
+ -werror -lerror -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128 \
-overview $(LOCAL_PATH)/core/java/overview.html \
framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
diff --git a/api/current.txt b/api/current.txt
index 7a2cecd..a083e57 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9370,6 +9370,7 @@
field public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED";
field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
+ field public static final java.lang.String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
@@ -9552,6 +9553,7 @@
field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
+ field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
@@ -10172,6 +10174,7 @@
method public int describeContents();
method public void dump(android.util.Printer, java.lang.String);
method public static java.lang.CharSequence getCategoryTitle(android.content.Context, int);
+ method public boolean isVirtualPreload();
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final int CATEGORY_AUDIO = 1; // 0x1
field public static final int CATEGORY_GAME = 0; // 0x0
@@ -10506,6 +10509,7 @@
method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
method public void removeSplit(java.lang.String) throws java.io.IOException;
method public void setStagingProgress(float);
+ method public void transfer(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static abstract class PackageInstaller.SessionCallback {
@@ -10523,10 +10527,16 @@
method public android.graphics.Bitmap getAppIcon();
method public java.lang.CharSequence getAppLabel();
method public java.lang.String getAppPackageName();
+ method public int getInstallLocation();
method public int getInstallReason();
method public java.lang.String getInstallerPackageName();
+ method public int getMode();
+ method public int getOriginatingUid();
+ method public android.net.Uri getOriginatingUri();
method public float getProgress();
+ method public android.net.Uri getReferrerUri();
method public int getSessionId();
+ method public long getSize();
method public boolean isActive();
method public boolean isSealed();
method public void writeToParcel(android.os.Parcel, int);
@@ -11902,7 +11912,7 @@
method public boolean needUpgrade(int);
method protected void onAllReferencesReleased();
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
- method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.OpenParams);
+ method public static android.database.sqlite.SQLiteDatabase openDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.OpenParams);
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.CursorFactory);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -11956,6 +11966,7 @@
public static final class SQLiteDatabase.OpenParams {
method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
method public android.database.DatabaseErrorHandler getErrorHandler();
+ method public long getIdleConnectionTimeout();
method public int getLookasideSlotCount();
method public int getLookasideSlotSize();
method public int getOpenFlags();
@@ -11969,6 +11980,7 @@
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
+ method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
}
@@ -12026,6 +12038,7 @@
method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void onOpen(android.database.sqlite.SQLiteDatabase);
method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
+ method public void setIdleConnectionTimeout(long);
method public void setLookasideConfig(int, int);
method public void setWriteAheadLoggingEnabled(boolean);
}
@@ -15855,7 +15868,6 @@
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
- field public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6; // 0x6
field public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8
}
@@ -22189,11 +22201,13 @@
field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
field public static final int DolbyVisionProfileDvavPen = 2; // 0x2
field public static final int DolbyVisionProfileDvavPer = 1; // 0x1
+ field public static final int DolbyVisionProfileDvavSe = 512; // 0x200
field public static final int DolbyVisionProfileDvheDen = 8; // 0x8
field public static final int DolbyVisionProfileDvheDer = 4; // 0x4
field public static final int DolbyVisionProfileDvheDtb = 128; // 0x80
field public static final int DolbyVisionProfileDvheDth = 64; // 0x40
field public static final int DolbyVisionProfileDvheDtr = 16; // 0x10
+ field public static final int DolbyVisionProfileDvheSt = 256; // 0x100
field public static final int DolbyVisionProfileDvheStn = 32; // 0x20
field public static final int H263Level10 = 1; // 0x1
field public static final int H263Level20 = 2; // 0x2
@@ -22737,6 +22751,7 @@
method public android.graphics.Bitmap getFrameAtTime(long, int);
method public android.graphics.Bitmap getFrameAtTime(long);
method public android.graphics.Bitmap getFrameAtTime();
+ method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int);
method public void release();
method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException;
@@ -37077,6 +37092,13 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.LuhnChecksumValidator> CREATOR;
}
+ public final class RegexValidator implements android.os.Parcelable android.service.autofill.Validator {
+ ctor public RegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.RegexValidator> CREATOR;
+ }
+
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
method public void onSuccess();
@@ -37117,13 +37139,6 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
}
- public final class SimpleRegexValidator implements android.os.Parcelable android.service.autofill.Validator {
- ctor public SimpleRegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.autofill.SimpleRegexValidator> CREATOR;
- }
-
public abstract interface Transformation {
}
@@ -39538,7 +39553,7 @@
method public android.os.PersistableBundle getConfigForSubId(int);
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 deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+ field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -39580,10 +39595,9 @@
field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
- field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
- field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
- field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -39640,7 +39654,7 @@
field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
- field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+ field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -40152,10 +40166,8 @@
method public static int getDefaultSmsSubscriptionId();
method public static int getDefaultSubscriptionId();
method public static int getDefaultVoiceSubscriptionId();
- method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
method public boolean isNetworkRoaming(int);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
- method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
@@ -40169,38 +40181,6 @@
method public void onSubscriptionsChanged();
}
- public final class SubscriptionPlan implements android.os.Parcelable {
- method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
- method public int describeContents();
- method public int getDataLimitBehavior();
- method public long getDataLimitBytes();
- method public long getDataUsageBytes();
- method public long getDataUsageTime();
- method public java.lang.CharSequence getSummary();
- method public java.lang.CharSequence getTitle();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL
- field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL
- field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR;
- field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1
- field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
- field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
- field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
- field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
- }
-
- public static class SubscriptionPlan.Builder {
- method public android.telephony.SubscriptionPlan build();
- method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
- method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
- method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
- method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
- method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence);
- }
-
public class TelephonyManager {
method public boolean canChangeDtmfToneLength();
method public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle);
@@ -41049,6 +41029,7 @@
method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public java.lang.String getNameForUid(int);
+ method public java.lang.String[] getNamesForUids(int[]);
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -49085,6 +49066,7 @@
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -49133,6 +49115,7 @@
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
method public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String>, android.webkit.ValueCallback<java.lang.Boolean>);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 27d3ee4..73b4ab0 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -149,6 +149,7 @@
field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
field public static final java.lang.String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS";
+ field public static final java.lang.String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS";
field public static final java.lang.String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
@@ -9907,6 +9908,7 @@
field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
field public static final deprecated java.lang.String ACTION_INSTALL_EPHEMERAL_PACKAGE = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
+ field public static final java.lang.String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
field public static final java.lang.String ACTION_INSTALL_INSTANT_APP_PACKAGE = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE";
field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
field public static final java.lang.String ACTION_INSTANT_APP_RESOLVER_SETTINGS = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS";
@@ -10759,6 +10761,7 @@
method public int describeContents();
method public void dump(android.util.Printer, java.lang.String);
method public static java.lang.CharSequence getCategoryTitle(android.content.Context, int);
+ method public boolean isVirtualPreload();
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final int CATEGORY_AUDIO = 1; // 0x1
field public static final int CATEGORY_GAME = 0; // 0x0
@@ -11179,12 +11182,14 @@
method public void abandon();
method public void close();
method public void commit(android.content.IntentSender);
+ method public void commitTransferred(android.content.IntentSender);
method public void fsync(java.io.OutputStream) throws java.io.IOException;
method public java.lang.String[] getNames() throws java.io.IOException;
method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException;
method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
method public void removeSplit(java.lang.String) throws java.io.IOException;
method public void setStagingProgress(float);
+ method public void transfer(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static abstract class PackageInstaller.SessionCallback {
@@ -11199,13 +11204,26 @@
public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
method public android.content.Intent createDetailsIntent();
method public int describeContents();
+ method public boolean getAllocateAggressive();
+ method public boolean getAllowDowngrade();
method public android.graphics.Bitmap getAppIcon();
method public java.lang.CharSequence getAppLabel();
method public java.lang.String getAppPackageName();
+ method public boolean getDontKillApp();
+ method public java.lang.String[] getGrantedRuntimePermissions();
+ method public boolean getInstallAsFullApp(boolean);
+ method public boolean getInstallAsInstantApp(boolean);
+ method public boolean getInstallAsVirtualPreload();
+ method public int getInstallLocation();
method public int getInstallReason();
method public java.lang.String getInstallerPackageName();
+ method public int getMode();
+ method public int getOriginatingUid();
+ method public android.net.Uri getOriginatingUri();
method public float getProgress();
+ method public android.net.Uri getReferrerUri();
method public int getSessionId();
+ method public long getSize();
method public boolean isActive();
method public boolean isSealed();
method public void writeToParcel(android.os.Parcel, int);
@@ -12697,7 +12715,7 @@
method public boolean needUpgrade(int);
method protected void onAllReferencesReleased();
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
- method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.OpenParams);
+ method public static android.database.sqlite.SQLiteDatabase openDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.OpenParams);
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.CursorFactory);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -12751,6 +12769,7 @@
public static final class SQLiteDatabase.OpenParams {
method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
method public android.database.DatabaseErrorHandler getErrorHandler();
+ method public long getIdleConnectionTimeout();
method public int getLookasideSlotCount();
method public int getLookasideSlotSize();
method public int getOpenFlags();
@@ -12764,6 +12783,7 @@
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
+ method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
}
@@ -12821,6 +12841,7 @@
method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void onOpen(android.database.sqlite.SQLiteDatabase);
method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
+ method public void setIdleConnectionTimeout(long);
method public void setLookasideConfig(int, int);
method public void setWriteAheadLoggingEnabled(boolean);
}
@@ -16669,7 +16690,6 @@
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
- field public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6; // 0x6
field public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8
}
@@ -17246,10 +17266,8 @@
field public static final int IDENTIFIER_TYPE_RDS_PI = 2; // 0x2
field public static final int IDENTIFIER_TYPE_SXM_CHANNEL = 13; // 0xd
field public static final int IDENTIFIER_TYPE_SXM_SERVICE_ID = 12; // 0xc
- field public static final int IDENTIFIER_TYPE_VENDOR1_PRIMARY = 14; // 0xe
- field public static final int IDENTIFIER_TYPE_VENDOR2_PRIMARY = 15; // 0xf
- field public static final int IDENTIFIER_TYPE_VENDOR3_PRIMARY = 16; // 0x10
- field public static final int IDENTIFIER_TYPE_VENDOR4_PRIMARY = 17; // 0x11
+ field public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_END = 1999; // 0x7cf
+ field public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_START = 1000; // 0x3e8
field public static final int PROGRAM_TYPE_AM = 1; // 0x1
field public static final int PROGRAM_TYPE_AM_HD = 3; // 0x3
field public static final int PROGRAM_TYPE_DAB = 5; // 0x5
@@ -17257,10 +17275,8 @@
field public static final int PROGRAM_TYPE_FM = 2; // 0x2
field public static final int PROGRAM_TYPE_FM_HD = 4; // 0x4
field public static final int PROGRAM_TYPE_SXM = 7; // 0x7
- field public static final int PROGRAM_TYPE_VENDOR1 = 8; // 0x8
- field public static final int PROGRAM_TYPE_VENDOR2 = 9; // 0x9
- field public static final int PROGRAM_TYPE_VENDOR3 = 10; // 0xa
- field public static final int PROGRAM_TYPE_VENDOR4 = 11; // 0xb
+ field public static final int PROGRAM_TYPE_VENDOR_END = 1999; // 0x7cf
+ field public static final int PROGRAM_TYPE_VENDOR_START = 1000; // 0x3e8
}
public static final class ProgramSelector.Identifier implements android.os.Parcelable {
@@ -17388,7 +17404,7 @@
method public java.lang.String getProduct();
method public java.lang.String getSerial();
method public java.lang.String getServiceName();
- method public java.lang.String getVendorInfo();
+ method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo();
method public java.lang.String getVersion();
method public boolean isBackgroundScanningSupported();
method public boolean isCaptureSupported();
@@ -17405,7 +17421,7 @@
method public android.hardware.radio.ProgramSelector getSelector();
method public int getSignalStrength();
method public deprecated int getSubChannel();
- method public java.lang.String getVendorInfo();
+ method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo();
method public boolean isDigital();
method public boolean isLive();
method public boolean isMuted();
@@ -17469,7 +17485,7 @@
method public abstract int getConfiguration(android.hardware.radio.RadioManager.BandConfig[]);
method public abstract boolean getMute();
method public abstract int getProgramInformation(android.hardware.radio.RadioManager.ProgramInfo[]);
- method public abstract java.util.List<android.hardware.radio.RadioManager.ProgramInfo> getProgramList(java.lang.String);
+ method public abstract java.util.List<android.hardware.radio.RadioManager.ProgramInfo> getProgramList(java.util.Map<java.lang.String, java.lang.String>);
method public abstract boolean hasControl();
method public abstract boolean isAnalogForced();
method public abstract boolean isAntennaConnected();
@@ -24132,11 +24148,13 @@
field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
field public static final int DolbyVisionProfileDvavPen = 2; // 0x2
field public static final int DolbyVisionProfileDvavPer = 1; // 0x1
+ field public static final int DolbyVisionProfileDvavSe = 512; // 0x200
field public static final int DolbyVisionProfileDvheDen = 8; // 0x8
field public static final int DolbyVisionProfileDvheDer = 4; // 0x4
field public static final int DolbyVisionProfileDvheDtb = 128; // 0x80
field public static final int DolbyVisionProfileDvheDth = 64; // 0x40
field public static final int DolbyVisionProfileDvheDtr = 16; // 0x10
+ field public static final int DolbyVisionProfileDvheSt = 256; // 0x100
field public static final int DolbyVisionProfileDvheStn = 32; // 0x20
field public static final int H263Level10 = 1; // 0x1
field public static final int H263Level20 = 2; // 0x2
@@ -24680,6 +24698,7 @@
method public android.graphics.Bitmap getFrameAtTime(long, int);
method public android.graphics.Bitmap getFrameAtTime(long);
method public android.graphics.Bitmap getFrameAtTime();
+ method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int);
method public void release();
method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException;
@@ -38649,6 +38668,7 @@
public final class TimeZoneRulesDataContract {
field public static final java.lang.String AUTHORITY = "com.android.timezone";
+ field public static final java.lang.String READER_PERMISSION = "android.permission.UPDATE_TIME_ZONE_RULES";
}
public static final class TimeZoneRulesDataContract.Operation {
@@ -40265,6 +40285,13 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.LuhnChecksumValidator> CREATOR;
}
+ public final class RegexValidator implements android.os.Parcelable android.service.autofill.Validator {
+ ctor public RegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.RegexValidator> CREATOR;
+ }
+
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
method public void onSuccess();
@@ -40305,13 +40332,6 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
}
- public final class SimpleRegexValidator implements android.os.Parcelable android.service.autofill.Validator {
- ctor public SimpleRegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.autofill.SimpleRegexValidator> CREATOR;
- }
-
public abstract interface Transformation {
}
@@ -43087,7 +43107,7 @@
method public void notifyConfigChangedForSubId(int);
method public void updateConfigForPhoneId(int, java.lang.String);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
- field public static final deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+ field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -43131,8 +43151,8 @@
field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
- field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
- field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -43189,7 +43209,7 @@
field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
- field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+ field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -44696,6 +44716,7 @@
method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public java.lang.String getNameForUid(int);
+ method public java.lang.String[] getNamesForUids(int[]);
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -52842,6 +52863,7 @@
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -52891,6 +52913,7 @@
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
method public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String>, android.webkit.ValueCallback<java.lang.Boolean>);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index 282e9d0..b57b82d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -9405,6 +9405,7 @@
field public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED";
field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
+ field public static final java.lang.String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
@@ -9587,6 +9588,7 @@
field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
+ field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
@@ -10209,6 +10211,7 @@
method public static java.lang.CharSequence getCategoryTitle(android.content.Context, int);
method public boolean isPrivilegedApp();
method public boolean isSystemApp();
+ method public boolean isVirtualPreload();
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final int CATEGORY_AUDIO = 1; // 0x1
field public static final int CATEGORY_GAME = 0; // 0x0
@@ -10544,6 +10547,7 @@
method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
method public void removeSplit(java.lang.String) throws java.io.IOException;
method public void setStagingProgress(float);
+ method public void transfer(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
}
public static abstract class PackageInstaller.SessionCallback {
@@ -10561,10 +10565,16 @@
method public android.graphics.Bitmap getAppIcon();
method public java.lang.CharSequence getAppLabel();
method public java.lang.String getAppPackageName();
+ method public int getInstallLocation();
method public int getInstallReason();
method public java.lang.String getInstallerPackageName();
+ method public int getMode();
+ method public int getOriginatingUid();
+ method public android.net.Uri getOriginatingUri();
method public float getProgress();
+ method public android.net.Uri getReferrerUri();
method public int getSessionId();
+ method public long getSize();
method public boolean isActive();
method public boolean isSealed();
method public void writeToParcel(android.os.Parcel, int);
@@ -11946,7 +11956,7 @@
method public boolean needUpgrade(int);
method protected void onAllReferencesReleased();
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
- method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.OpenParams);
+ method public static android.database.sqlite.SQLiteDatabase openDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.OpenParams);
method public static android.database.sqlite.SQLiteDatabase openDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.io.File, android.database.sqlite.SQLiteDatabase.CursorFactory);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -12000,6 +12010,7 @@
public static final class SQLiteDatabase.OpenParams {
method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
method public android.database.DatabaseErrorHandler getErrorHandler();
+ method public long getIdleConnectionTimeout();
method public int getLookasideSlotCount();
method public int getLookasideSlotSize();
method public int getOpenFlags();
@@ -12013,6 +12024,7 @@
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
+ method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
}
@@ -12032,6 +12044,31 @@
ctor public SQLiteDatatypeMismatchException(java.lang.String);
}
+ public final class SQLiteDebug {
+ method public static void dump(android.util.Printer, java.lang.String[]);
+ method public static android.database.sqlite.SQLiteDebug.PagerStats getDatabaseInfo();
+ field public static final boolean DEBUG_SQL_LOG;
+ field public static final boolean DEBUG_SQL_STATEMENTS;
+ field public static final boolean DEBUG_SQL_TIME;
+ }
+
+ public static class SQLiteDebug.DbStats {
+ ctor public SQLiteDebug.DbStats(java.lang.String, long, long, int, int, int, int);
+ field public java.lang.String cache;
+ field public java.lang.String dbName;
+ field public long dbSize;
+ field public int lookaside;
+ field public long pageSize;
+ }
+
+ public static class SQLiteDebug.PagerStats {
+ ctor public SQLiteDebug.PagerStats();
+ field public java.util.ArrayList<android.database.sqlite.SQLiteDebug.DbStats> dbStats;
+ field public int largestMemAlloc;
+ field public int memoryUsed;
+ field public int pageCacheOverflow;
+ }
+
public class SQLiteDiskIOException extends android.database.sqlite.SQLiteException {
ctor public SQLiteDiskIOException();
ctor public SQLiteDiskIOException(java.lang.String);
@@ -12070,6 +12107,7 @@
method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void onOpen(android.database.sqlite.SQLiteDatabase);
method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
+ method public void setIdleConnectionTimeout(long);
method public void setLookasideConfig(int, int);
method public void setWriteAheadLoggingEnabled(boolean);
}
@@ -15908,7 +15946,6 @@
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
- field public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6; // 0x6
field public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8
}
@@ -22300,11 +22337,13 @@
field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
field public static final int DolbyVisionProfileDvavPen = 2; // 0x2
field public static final int DolbyVisionProfileDvavPer = 1; // 0x1
+ field public static final int DolbyVisionProfileDvavSe = 512; // 0x200
field public static final int DolbyVisionProfileDvheDen = 8; // 0x8
field public static final int DolbyVisionProfileDvheDer = 4; // 0x4
field public static final int DolbyVisionProfileDvheDtb = 128; // 0x80
field public static final int DolbyVisionProfileDvheDth = 64; // 0x40
field public static final int DolbyVisionProfileDvheDtr = 16; // 0x10
+ field public static final int DolbyVisionProfileDvheSt = 256; // 0x100
field public static final int DolbyVisionProfileDvheStn = 32; // 0x20
field public static final int H263Level10 = 1; // 0x1
field public static final int H263Level20 = 2; // 0x2
@@ -22848,6 +22887,7 @@
method public android.graphics.Bitmap getFrameAtTime(long, int);
method public android.graphics.Bitmap getFrameAtTime(long);
method public android.graphics.Bitmap getFrameAtTime();
+ method public android.graphics.Bitmap getScaledFrameAtTime(long, int, int, int);
method public void release();
method public void setDataSource(java.lang.String) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.lang.IllegalArgumentException;
@@ -37244,6 +37284,14 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.LuhnChecksumValidator> CREATOR;
}
+ public final class RegexValidator implements android.os.Parcelable android.service.autofill.Validator {
+ ctor public RegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
+ method public int describeContents();
+ method public boolean isValid(android.service.autofill.ValueFinder);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.RegexValidator> CREATOR;
+ }
+
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
method public void onSuccess();
@@ -37284,14 +37332,6 @@
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveRequest> CREATOR;
}
- public final class SimpleRegexValidator implements android.os.Parcelable android.service.autofill.Validator {
- ctor public SimpleRegexValidator(android.view.autofill.AutofillId, java.util.regex.Pattern);
- method public int describeContents();
- method public boolean isValid(android.service.autofill.ValueFinder);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.autofill.SimpleRegexValidator> CREATOR;
- }
-
public abstract interface Transformation {
}
@@ -39764,7 +39804,7 @@
method public android.os.PersistableBundle getConfigForSubId(int);
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 deprecated int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
+ field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
field public static final java.lang.String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -39806,10 +39846,9 @@
field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
field public static final java.lang.String KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING = "config_ims_package_override_string";
- field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
- field public static final deprecated java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
- field public static final deprecated java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
+ field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final java.lang.String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
@@ -39866,7 +39905,7 @@
field public static final java.lang.String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
field public static final java.lang.String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
- field public static final deprecated java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
+ field public static final java.lang.String KEY_MONTHLY_DATA_CYCLE_DAY_INT = "monthly_data_cycle_day_int";
field public static final java.lang.String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -40378,10 +40417,8 @@
method public static int getDefaultSmsSubscriptionId();
method public static int getDefaultSubscriptionId();
method public static int getDefaultVoiceSubscriptionId();
- method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
method public boolean isNetworkRoaming(int);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
- method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
@@ -40395,38 +40432,6 @@
method public void onSubscriptionsChanged();
}
- public final class SubscriptionPlan implements android.os.Parcelable {
- method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
- method public int describeContents();
- method public int getDataLimitBehavior();
- method public long getDataLimitBytes();
- method public long getDataUsageBytes();
- method public long getDataUsageTime();
- method public java.lang.CharSequence getSummary();
- method public java.lang.CharSequence getTitle();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL
- field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL
- field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR;
- field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1
- field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
- field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
- field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
- field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
- }
-
- public static class SubscriptionPlan.Builder {
- method public android.telephony.SubscriptionPlan build();
- method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
- method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
- method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
- method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
- method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence);
- }
-
public class TelephonyManager {
method public boolean canChangeDtmfToneLength();
method public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle);
@@ -41278,6 +41283,7 @@
method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public java.lang.String getNameForUid(int);
+ method public java.lang.String[] getNamesForUids(int[]);
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -49507,6 +49513,7 @@
method public int getRendererRequestedPriority();
method public deprecated float getScale();
method public android.webkit.WebSettings getSettings();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
method public java.lang.String getTitle();
method public java.lang.String getUrl();
method public android.webkit.WebChromeClient getWebChromeClient();
@@ -49555,6 +49562,7 @@
method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
method public void setRendererPriorityPolicy(int, boolean);
method public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String>, android.webkit.ValueCallback<java.lang.Boolean>);
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
method public deprecated void setVerticalScrollbarOverlay(boolean);
method public void setWebChromeClient(android.webkit.WebChromeClient);
method public static void setWebContentsDebuggingEnabled(boolean);
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index c6d83f5..b69ef1c 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -152,7 +152,7 @@
System.out.println(pretty);
} else {
if (results != null) {
- for (String key : results.keySet()) {
+ for (String key : sorted(results.keySet())) {
System.out.println(
"INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
}
@@ -163,6 +163,10 @@
@Override
public void onError(String errorText, boolean commandError) {
+ if (mRawMode) {
+ System.out.println("onError: commandError=" + commandError + " message="
+ + errorText);
+ }
// The regular BaseCommand error printing will print the commandErrors.
if (!commandError) {
System.out.println(errorText);
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 2366878..35f8bbb 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -116,13 +116,6 @@
int main(int argc, char** argv)
{
- // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
- // not allowed to spawn any additional threads, but we still spawn
- // a binder thread from userspace when we call startThreadPool().
- // See b/36066697 for rationale
- ProcessState::self()->setThreadPoolMaxThreadCount(0);
- ProcessState::self()->startThreadPool();
-
const char* pname = argv[0];
bool png = false;
int32_t displayId = DEFAULT_DISPLAY_ID;
@@ -182,11 +175,19 @@
ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270
};
+ // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
+ // not allowed to spawn any additional threads, but we still spawn
+ // a binder thread from userspace when we call startThreadPool().
+ // See b/36066697 for rationale
+ ProcessState::self()->setThreadPoolMaxThreadCount(0);
+ ProcessState::self()->startThreadPool();
+
ScreenshotClient screenshot;
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
if (display == NULL) {
fprintf(stderr, "Unable to get handle for display %d\n", displayId);
- return 1;
+ // b/36066697: Avoid running static destructors.
+ _exit(1);
}
Vector<DisplayInfo> configs;
@@ -195,7 +196,8 @@
if (static_cast<size_t>(activeConfig) >= configs.size()) {
fprintf(stderr, "Active config %d not inside configs (size %zu)\n",
activeConfig, configs.size());
- return 1;
+ // b/36066697: Avoid running static destructors.
+ _exit(1);
}
uint8_t displayOrientation = configs[activeConfig].orientation;
uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
diff --git a/cmds/svc/src/com/android/commands/svc/WifiCommand.java b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
index 633dd97..e31cb53 100644
--- a/cmds/svc/src/com/android/commands/svc/WifiCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
@@ -51,6 +51,10 @@
if (validCommand) {
IWifiManager wifiMgr
= IWifiManager.Stub.asInterface(ServiceManager.getService(Context.WIFI_SERVICE));
+ if (wifiMgr == null) {
+ System.err.println("Wi-Fi service is not ready");
+ return;
+ }
try {
wifiMgr.setWifiEnabled("com.android.shell", flag);
}
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 5f023bd..d11f0ba 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -3114,6 +3114,7 @@
android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE$1
android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
android.os.AsyncResult
+android.os.AsyncTask
android.os.AsyncTask$1
android.os.AsyncTask$2
android.os.AsyncTask$3
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index af0a204..cec5db9 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -612,7 +612,7 @@
/**
* Get the controller for fingerprint gestures. This feature requires {@link
- * AccessibilityServiceInfo#CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES}.
+ * AccessibilityServiceInfo#CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES}.
*
*<strong>Note: </strong> The service must be connected before this method is called.
*
diff --git a/core/java/android/accessibilityservice/FingerprintGestureController.java b/core/java/android/accessibilityservice/FingerprintGestureController.java
index 9f04cea..c30030d 100644
--- a/core/java/android/accessibilityservice/FingerprintGestureController.java
+++ b/core/java/android/accessibilityservice/FingerprintGestureController.java
@@ -29,11 +29,11 @@
* sensor, as long as the device has a sensor capable of detecting gestures.
* <p>
* This capability must be declared by the service as
- * {@link AccessibilityServiceInfo#CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES}. It also requires
+ * {@link AccessibilityServiceInfo#CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES}. It also requires
* the permission {@link android.Manifest.permission#USE_FINGERPRINT}.
* <p>
* Because capturing fingerprint gestures may have side effects, services with the capability only
- * capture gestures when {@link AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} is set.
+ * capture gestures when {@link AccessibilityServiceInfo#FLAG_REQUEST_FINGERPRINT_GESTURES} is set.
* <p>
* <strong>Note: </strong>The fingerprint sensor is used for authentication in critical use cases,
* so services must carefully design their user's experience when performing gestures on the sensor.
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index a209d28..dd6ad55 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -395,7 +395,7 @@
/**
* Key to set default visibility for applications which don't satisfy conditions in
- * {@link PACKAGE_NAME_KEY_LEGACY_VISIBLE}. If the value was not set by authenticator
+ * {@link #PACKAGE_NAME_KEY_LEGACY_VISIBLE}. If the value was not set by authenticator
* {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used.
*/
public static final String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE =
@@ -616,7 +616,7 @@
* not authorized to view all accounts. This method can only be called by system apps and
* authenticators managing the type.
* Beginning API level {@link android.os.Build.VERSION_CODES#O} it also return accounts
- * which user can make visible to the application (see {@link VISIBILITY_USER_MANAGED_VISIBLE}).
+ * which user can make visible to the application (see {@link #VISIBILITY_USER_MANAGED_VISIBLE}).
*
* @param type The type of accounts to return, null to retrieve all accounts
* @param packageName The package name of the app for which the accounts are to be returned
@@ -654,7 +654,7 @@
* of accounts made visible to it by user
* (see {@link #newChooseAccountIntent(Account, List, String[], String,
* String, String[], Bundle)}) or AbstractAcccountAuthenticator
- * using {@link setAccountVisibility}.
+ * using {@link #setAccountVisibility}.
* {@link android.Manifest.permission#GET_ACCOUNTS} permission is not used.
*
* <p>
@@ -800,7 +800,7 @@
* of accounts made visible to it by user
* (see {@link #newChooseAccountIntent(Account, List, String[], String,
* String, String[], Bundle)}) or AbstractAcccountAuthenticator
- * using {@link setAccountVisibility}.
+ * using {@link #setAccountVisibility}.
* {@link android.Manifest.permission#GET_ACCOUNTS} permission is not used.
*
* <p>
@@ -2716,7 +2716,7 @@
* On success the activity returns a Bundle with the account name and type specified using
* keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
* Chosen account is marked as {@link #VISIBILITY_USER_MANAGED_VISIBLE} to the caller
- * (see {@link setAccountVisibility}) and will be returned to it in consequent
+ * (see {@link #setAccountVisibility}) and will be returned to it in consequent
* {@link #getAccountsByType}) calls.
* <p>
* The most common case is to call this with one account type, e.g.:
@@ -2771,7 +2771,7 @@
* On success the activity returns a Bundle with the account name and type specified using
* keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
* Chosen account is marked as {@link #VISIBILITY_USER_MANAGED_VISIBLE} to the caller
- * (see {@link setAccountVisibility}) and will be returned to it in consequent
+ * (see {@link #setAccountVisibility}) and will be returned to it in consequent
* {@link #getAccountsByType}) calls.
* <p>
* The most common case is to call this with one account type, e.g.:
diff --git a/core/java/android/annotation/TargetApi.java b/core/java/android/annotation/TargetApi.java
index ea17890..975318e 100644
--- a/core/java/android/annotation/TargetApi.java
+++ b/core/java/android/annotation/TargetApi.java
@@ -16,6 +16,7 @@
package android.annotation;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
@@ -25,7 +26,7 @@
/** Indicates that Lint should treat this type as targeting a given API level, no matter what the
project target is. */
-@Target({TYPE, METHOD, CONSTRUCTOR})
+@Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface TargetApi {
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d03b347..43693e1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4893,7 +4893,8 @@
// If the new config is the same as the config this Activity is already running with and
// the override config also didn't change, then don't bother calling
// onConfigurationChanged.
- int diff = activity.mCurrentConfig.diff(newConfig);
+ final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
+
if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken,
amOverrideConfig)) {
// Always send the task-level config changes. For system-level configuration, if
@@ -4981,6 +4982,14 @@
int configDiff = 0;
+ // This flag tracks whether the new configuration is fundamentally equivalent to the
+ // existing configuration. This is necessary to determine whether non-activity
+ // callbacks should receive notice when the only changes are related to non-public fields.
+ // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag
+ // as that method uses the same check on the activity config override as well.
+ final boolean equivalent = config != null && mConfiguration != null
+ && (0 == mConfiguration.diffPublicOnly(config));
+
synchronized (mResourcesManager) {
if (mPendingConfiguration != null) {
if (!mPendingConfiguration.isOtherSeqNewer(config)) {
@@ -5037,7 +5046,7 @@
Activity a = (Activity) cb;
performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
config);
- } else {
+ } else if (!equivalent) {
performConfigurationChanged(cb, config);
}
}
@@ -5709,6 +5718,7 @@
// probably end up doing the same disk access.
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
+ final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
@@ -5736,17 +5746,21 @@
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
+ try {
+ mInstrumentation.callApplicationOnCreate(app);
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(app, e)) {
+ throw new RuntimeException(
+ "Unable to create application " + app.getClass().getName()
+ + ": " + e.toString(), e);
+ }
+ }
} finally {
- StrictMode.setThreadPolicy(savedPolicy);
- }
-
- try {
- mInstrumentation.callApplicationOnCreate(app);
- } catch (Exception e) {
- if (!mInstrumentation.onException(app, e)) {
- throw new RuntimeException(
- "Unable to create application " + app.getClass().getName()
- + ": " + e.toString(), e);
+ // If the app targets < O-MR1, or doesn't change the thread policy
+ // during startup, clobber the policy to maintain behavior of b/36951662
+ if (data.appInfo.targetSdkVersion <= Build.VERSION_CODES.O
+ || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
+ StrictMode.setThreadPolicy(savedPolicy);
}
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index acceed0..0eafdec 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -31,7 +31,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.ChangedPackages;
import android.content.pm.ComponentInfo;
-import android.content.pm.InstantAppInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IOnPermissionsChangeListener;
import android.content.pm.IPackageDataObserver;
@@ -40,6 +39,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
@@ -88,13 +88,14 @@
import android.util.Log;
import android.view.Display;
-import dalvik.system.VMRuntime;
-
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
import com.android.internal.util.UserIcons;
+
+import dalvik.system.VMRuntime;
+
import libcore.util.EmptyArray;
import java.lang.ref.WeakReference;
@@ -285,7 +286,8 @@
public PermissionInfo getPermissionInfo(String name, int flags)
throws NameNotFoundException {
try {
- PermissionInfo pi = mPM.getPermissionInfo(name, flags);
+ PermissionInfo pi = mPM.getPermissionInfo(name,
+ mContext.getOpPackageName(), flags);
if (pi != null) {
return pi;
}
@@ -705,6 +707,15 @@
}
@Override
+ public String[] getNamesForUids(int[] uids) {
+ try {
+ return mPM.getNamesForUids(uids);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
public int getUidForSharedUser(String sharedUserName)
throws NameNotFoundException {
try {
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
index 13f288a..f99d1a8 100644
--- a/core/java/android/app/DexLoadReporter.java
+++ b/core/java/android/app/DexLoadReporter.java
@@ -19,6 +19,7 @@
import android.os.FileUtils;
import android.os.RemoteException;
import android.os.SystemProperties;
+import android.system.ErrnoException;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -26,8 +27,11 @@
import dalvik.system.BaseDexClassLoader;
import dalvik.system.VMRuntime;
+import libcore.io.Libcore;
+
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -86,29 +90,50 @@
}
@Override
- public void report(List<String> dexPaths) {
- if (dexPaths.isEmpty()) {
+ public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) {
+ if (classLoadersChain.size() != classPaths.size()) {
+ Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch");
return;
}
+ if (classPaths.isEmpty()) {
+ Slog.wtf(TAG, "Bad call to DexLoadReporter: empty dex paths");
+ return;
+ }
+
+ // The first element of classPaths is the list of dex files that should be registered.
+ // The classpath is represented as a list of dex files separated by File.pathSeparator.
+ String[] dexPathsForRegistration = classPaths.get(0).split(File.pathSeparator);
+ if (dexPathsForRegistration.length == 0) {
+ // No dex files to register.
+ return;
+ }
+
// Notify the package manager about the dex loads unconditionally.
// The load might be for either a primary or secondary dex file.
- notifyPackageManager(dexPaths);
- // Check for secondary dex files and register them for profiling if
- // possible.
- registerSecondaryDexForProfiling(dexPaths);
+ notifyPackageManager(classLoadersChain, classPaths);
+ // Check for secondary dex files and register them for profiling if possible.
+ // Note that we only register the dex paths belonging to the first class loader.
+ registerSecondaryDexForProfiling(dexPathsForRegistration);
}
- private void notifyPackageManager(List<String> dexPaths) {
+ private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain,
+ List<String> classPaths) {
+ // Get the class loader names for the binder call.
+ List<String> classLoadersNames = new ArrayList<>(classPaths.size());
+ for (BaseDexClassLoader bdc : classLoadersChain) {
+ classLoadersNames.add(bdc.getClass().getName());
+ }
String packageName = ActivityThread.currentPackageName();
try {
ActivityThread.getPackageManager().notifyDexLoad(
- packageName, dexPaths, VMRuntime.getRuntime().vmInstructionSet());
+ packageName, classLoadersNames, classPaths,
+ VMRuntime.getRuntime().vmInstructionSet());
} catch (RemoteException re) {
Slog.e(TAG, "Failed to notify PM about dex load for package " + packageName, re);
}
}
- private void registerSecondaryDexForProfiling(List<String> dexPaths) {
+ private void registerSecondaryDexForProfiling(String[] dexPaths) {
if (!SystemProperties.getBoolean("dalvik.vm.dexopt.secondary", false)) {
return;
}
@@ -129,22 +154,50 @@
// The dex path is not a secondary dex file. Nothing to do.
return;
}
- File secondaryProfile = getSecondaryProfileFile(dexPath);
+
+ File realDexPath;
try {
- // Create the profile if not already there.
- // Returns true if the file was created, false if the file already exists.
- // or throws exceptions in case of errors.
+ // Secondary dex profiles are stored in the oat directory, next to the real dex file
+ // and have the same name with 'cur.prof' appended. We use the realpath because that
+ // is what installd is using when processing the dex file.
+ // NOTE: Keep in sync with installd.
+ realDexPath = new File(Libcore.os.realpath(dexPath));
+ } catch (ErrnoException ex) {
+ Slog.e(TAG, "Failed to get the real path of secondary dex " + dexPath
+ + ":" + ex.getMessage());
+ // Do not continue with registration if we could not retrieve the real path.
+ return;
+ }
+
+ // NOTE: Keep this in sync with installd expectations.
+ File secondaryProfileDir = new File(realDexPath.getParent(), "oat");
+ File secondaryProfile = new File(secondaryProfileDir, realDexPath.getName() + ".cur.prof");
+
+ // Create the profile if not already there.
+ // Returns true if the file was created, false if the file already exists.
+ // or throws exceptions in case of errors.
+ if (!secondaryProfileDir.exists()) {
+ if (!secondaryProfileDir.mkdir()) {
+ Slog.e(TAG, "Could not create the profile directory: " + secondaryProfile);
+ // Do not continue with registration if we could not create the oat dir.
+ return;
+ }
+ }
+
+ try {
boolean created = secondaryProfile.createNewFile();
if (DEBUG && created) {
Slog.i(TAG, "Created profile for secondary dex: " + secondaryProfile);
}
} catch (IOException ex) {
- Slog.e(TAG, "Failed to create profile for secondary dex " + secondaryProfile +
- ":" + ex.getMessage());
- // Don't move forward with the registration if we failed to create the profile.
+ Slog.e(TAG, "Failed to create profile for secondary dex " + dexPath
+ + ":" + ex.getMessage());
+ // Do not continue with registration if we could not create the profile files.
return;
}
+ // If we got here, the dex paths is a secondary dex and we were able to create the profile.
+ // Register the path to the runtime.
VMRuntime.registerAppInfo(secondaryProfile.getPath(), new String[] { dexPath });
}
@@ -158,11 +211,4 @@
}
return false;
}
-
- // Secondary dex profiles are stored next to the dex file and have the same
- // name with '.prof' appended.
- // NOTE: Keep in sync with installd.
- private File getSecondaryProfileFile(String dexPath) {
- return new File(dexPath + ".prof");
- }
}
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 0e33934..49d58eb 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -144,15 +144,15 @@
* or {@link WallpaperManager#FLAG_SYSTEM}
* @return colors of chosen wallpaper
*/
- WallpaperColors getWallpaperColors(int which);
+ WallpaperColors getWallpaperColors(int which, int userId);
/**
* Register a callback to receive color updates
*/
- void registerWallpaperColorsCallback(IWallpaperManagerCallback cb);
+ void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
/**
* Unregister a callback that was receiving color updates
*/
- void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb);
+ void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
}
diff --git a/core/java/android/app/IWallpaperManagerCallback.aidl b/core/java/android/app/IWallpaperManagerCallback.aidl
index 0cfbaef..ea0ceab 100644
--- a/core/java/android/app/IWallpaperManagerCallback.aidl
+++ b/core/java/android/app/IWallpaperManagerCallback.aidl
@@ -34,6 +34,6 @@
/**
* Called when wallpaper colors change
*/
- void onWallpaperColorsChanged(in WallpaperColors colors, int which);
+ void onWallpaperColorsChanged(in WallpaperColors colors, int which, int userId);
}
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index e4a22c4..95ec24c 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -43,6 +43,13 @@
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*
+ * <p class="note"><b>Note:</b> IntentService is subject to all the
+ * <a href="/preview/features/background.html">background execution limits</a>
+ * imposed with Android 8.0 (API level 26). In most cases, you are better off
+ * using {@link android.support.v4.app.JobIntentService}, which uses jobs
+ * instead of services when running on Android 8.0 or higher.
+ * </p>
+ *
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For a detailed discussion about how to create services, read the
@@ -50,6 +57,7 @@
* guide.</p>
* </div>
*
+ * @see android.support.v4.app.JobIntentService
* @see android.os.AsyncTask
*/
public abstract class IntentService extends Service {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index c0381d6..76643d6 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -298,7 +298,9 @@
}
/**
- * Callback passed to {@link KeyguardManager#dismissKeyguard} to notify caller of result.
+ * Callback passed to
+ * {@link KeyguardManager#requestDismissKeyguard(Activity, KeyguardDismissCallback)}
+ * to notify caller of result.
*/
public static abstract class KeyguardDismissCallback {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 0f0c4ba..34343e9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -204,7 +204,12 @@
public static final int IMPORTANCE_NONE = 0;
/**
- * Min notification importance: only shows in the shade, below the fold.
+ * Min notification importance: only shows in the shade, below the fold. This should
+ * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
+ * since a foreground service is supposed to be something the user cares about so it does
+ * not make semantic sense to mark its notification as minimum importance. If you do this
+ * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
+ * a higher-priority notification about your app running in the background.
*/
public static final int IMPORTANCE_MIN = 1;
@@ -416,12 +421,16 @@
* Creates a notification channel that notifications can be posted to.
*
* This can also be used to restore a deleted channel and to update an existing channel's
- * name and description.
+ * name, description, and/or importance.
*
* <p>The name and description should only be changed if the locale changes
* or in response to the user renaming this channel. For example, if a user has a channel
* named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
* to 'John Smith,' the channel can be renamed to match.
+ *
+ * <p>The importance of an existing channel will only be changed if the new importance is lower
+ * than the current value and the user has not altered any settings on this channel.
+ *
* All other fields are ignored for channels that already exist.
*
* @param channel the channel to create. Note that the created channel may differ from this
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 6f326de..595ecd2 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -44,8 +44,6 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Predicate;
@@ -417,7 +415,12 @@
if (activityResources == null) {
return overrideConfig == null;
} else {
- return Objects.equals(activityResources.overrideConfig, overrideConfig);
+ // The two configurations must either be equal or publicly equivalent to be
+ // considered the same.
+ return Objects.equals(activityResources.overrideConfig, overrideConfig)
+ || (overrideConfig != null && activityResources.overrideConfig != null
+ && 0 == overrideConfig.diffPublicOnly(
+ activityResources.overrideConfig));
}
}
}
@@ -984,8 +987,6 @@
}
}
- invalidatePath("/");
-
redirectResourcesToNewImplLocked(updatedResourceKeys);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index d0791cf..2a8130f 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -408,4 +408,13 @@
return new Size(newWidth, newHeight);
}
+
+ @Override
+ public String toString() {
+ final StringBuilder colors = new StringBuilder();
+ for (int i = 0; i < mMainColors.size(); i++) {
+ colors.append(Integer.toHexString(mMainColors.get(i).toArgb())).append(" ");
+ }
+ return "[WallpaperColors: " + colors.toString() + "h: " + mColorHints + "]";
+ }
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 0398b47..16d0214 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -307,13 +307,14 @@
* changes its colors.
* @param callback Listener
* @param handler Thread to call it from. Main thread if null.
+ * @param userId Owner of the wallpaper or UserHandle.USER_ALL
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
- @Nullable Handler handler) {
+ @Nullable Handler handler, int userId) {
synchronized (this) {
if (!mColorCallbackRegistered) {
try {
- mService.registerWallpaperColorsCallback(this);
+ mService.registerWallpaperColorsCallback(this, userId);
mColorCallbackRegistered = true;
} catch (RemoteException e) {
// Failed, service is gone
@@ -328,15 +329,17 @@
* Stop listening to wallpaper color events.
*
* @param callback listener
+ * @param userId Owner of the wallpaper or UserHandle.USER_ALL
*/
- public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) {
+ public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+ int userId) {
synchronized (this) {
mColorListeners.removeIf(pair -> pair.first == callback);
if (mColorListeners.size() == 0 && mColorCallbackRegistered) {
mColorCallbackRegistered = false;
try {
- mService.unregisterWallpaperColorsCallback(this);
+ mService.unregisterWallpaperColorsCallback(this, userId);
} catch (RemoteException e) {
// Failed, service is gone
Log.w(TAG, "Can't unregister color updates", e);
@@ -346,7 +349,7 @@
}
@Override
- public void onWallpaperColorsChanged(WallpaperColors colors, int which) {
+ public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
synchronized (this) {
for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) {
Handler handler = listener.second;
@@ -361,21 +364,21 @@
stillExists = mColorListeners.contains(listener);
}
if (stillExists) {
- listener.first.onColorsChanged(colors, which);
+ listener.first.onColorsChanged(colors, which, userId);
}
});
}
}
}
- WallpaperColors getWallpaperColors(int which) {
+ WallpaperColors getWallpaperColors(int which, int userId) {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException(
"Must request colors for exactly one kind of wallpaper");
}
try {
- return mService.getWallpaperColors(which);
+ return mService.getWallpaperColors(which, userId);
} catch (RemoteException e) {
// Can't get colors, connection lost.
}
@@ -857,7 +860,7 @@
* @param listener A listener to register
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
- sGlobals.addOnColorsChangedListener(listener, null);
+ addOnColorsChangedListener(listener, null);
}
/**
@@ -868,25 +871,61 @@
*/
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
@NonNull Handler handler) {
- sGlobals.addOnColorsChangedListener(listener, handler);
+ addOnColorsChangedListener(listener, handler, mContext.getUserId());
+ }
+
+ /**
+ * Registers a listener to get notified when the wallpaper colors change
+ * @param listener A listener to register
+ * @param handler Where to call it from. Will be called from the main thread
+ * if null.
+ * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+ * @hide
+ */
+ public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+ @NonNull Handler handler, int userId) {
+ sGlobals.addOnColorsChangedListener(listener, handler, userId);
}
/**
* Stop listening to color updates.
- * @param callback A callback to unsubscribe
+ * @param callback A callback to unsubscribe.
*/
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) {
- sGlobals.removeOnColorsChangedListener(callback);
+ removeOnColorsChangedListener(callback, mContext.getUserId());
+ }
+
+ /**
+ * Stop listening to color updates.
+ * @param callback A callback to unsubscribe.
+ * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+ * @hide
+ */
+ public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+ int userId) {
+ sGlobals.removeOnColorsChangedListener(callback, userId);
}
/**
* Get the primary colors of a wallpaper
* @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK}
- * @return a list of colors ordered by priority
+ * @return {@link WallpaperColors} or null if colors are unknown.
*/
public @Nullable WallpaperColors getWallpaperColors(int which) {
- return sGlobals.getWallpaperColors(which);
+ return getWallpaperColors(which, mContext.getUserId());
+ }
+
+ /**
+ * Get the primary colors of a wallpaper
+ * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
+ * {@link #FLAG_LOCK}
+ * @param userId Owner of the wallpaper.
+ * @return {@link WallpaperColors} or null if colors are unknown.
+ * @hide
+ */
+ public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
+ return sGlobals.getWallpaperColors(which, userId);
}
/**
@@ -1902,9 +1941,9 @@
}
@Override
- public void onWallpaperColorsChanged(WallpaperColors colors, int which)
+ public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId)
throws RemoteException {
- sGlobals.onWallpaperColorsChanged(colors, which);
+ sGlobals.onWallpaperColorsChanged(colors, which, userId);
}
}
@@ -1921,5 +1960,19 @@
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
*/
void onColorsChanged(WallpaperColors colors, int which);
+
+ /**
+ * Called when colors change.
+ * A {@link android.app.WallpaperColors} object containing a simplified
+ * color histogram will be given.
+ *
+ * @param colors Wallpaper color info
+ * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
+ * @param userId Owner of the wallpaper
+ * @hide
+ */
+ default void onColorsChanged(WallpaperColors colors, int which, int userId) {
+ onColorsChanged(colors, which);
+ }
}
}
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index f987468..36f5f96 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -18,20 +18,19 @@
import android.app.WallpaperManager;
import android.content.Context;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.util.Slog;
-import android.view.Display;
-import android.view.WindowManager;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
/**
- * Helper for backing up / restoring wallpapers. Basically an AbsoluteFileBackupHelper,
- * but with logic for deciding what to do with restored wallpaper images.
+ * We no longer back up wallpapers with this helper, but we do need to process restores
+ * of legacy backup payloads. We just take the restored image as-is and apply it as the
+ * system wallpaper using the public "set the wallpaper" API.
*
* @hide
*/
@@ -39,83 +38,34 @@
private static final String TAG = "WallpaperBackupHelper";
private static final boolean DEBUG = false;
- // If 'true', then apply an acceptable-size heuristic at restore time, dropping back
- // to the factory default wallpaper if the restored one differs "too much" from the
- // device's preferred wallpaper image dimensions.
- private static final boolean REJECT_OUTSIZED_RESTORE = false;
-
- // When outsized restore rejection is enabled, this is the maximum ratio between the
- // source and target image heights that will be permitted. The ratio is checked both
- // ways (i.e. >= MAX, or <= 1/MAX) to validate restores from both largeer-than-target
- // and smaller-than-target sources.
- private static final double MAX_HEIGHT_RATIO = 1.35;
-
- // The height ratio check when applying larger images on smaller screens is separate;
- // in current policy we accept any such restore regardless of the relative dimensions.
- private static final double MIN_HEIGHT_RATIO = 0;
-
- // This path must match what the WallpaperManagerService uses
- // TODO: Will need to change if backing up non-primary user's wallpaper
- // http://b/22388012
- public static final String WALLPAPER_IMAGE =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
- "wallpaper").getAbsolutePath();
- public static final String WALLPAPER_ORIG_IMAGE =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
- "wallpaper_orig").getAbsolutePath();
- public static final String WALLPAPER_INFO =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
- "wallpaper_info.xml").getAbsolutePath();
- // Use old keys to keep legacy data compatibility and avoid writing two wallpapers
+ // Key that legacy wallpaper imagery was stored under
public static final String WALLPAPER_IMAGE_KEY =
"/data/data/com.android.settings/files/wallpaper";
public static final String WALLPAPER_INFO_KEY = "/data/system/wallpaper_info.xml";
- // Stage file - should be adjacent to the WALLPAPER_IMAGE location. The wallpapers
- // will be saved to this file from the restore stream, then renamed to the proper
- // location if it's deemed suitable.
- // TODO: Will need to change if backing up non-primary user's wallpaper
- // http://b/22388012
+ // Stage file that the restored imagery is stored to prior to being applied
+ // as the system wallpaper.
private static final String STAGE_FILE =
new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
"wallpaper-tmp").getAbsolutePath();
- Context mContext;
- String[] mFiles;
- String[] mKeys;
- double mDesiredMinWidth;
- double mDesiredMinHeight;
+ private final String[] mKeys;
+ private final WallpaperManager mWpm;
/**
- * Construct a helper for backing up / restoring the files at the given absolute locations
- * within the file system.
+ * Legacy wallpaper restores, from back when the imagery was stored under the
+ * "android" system package as file key/value entities.
*
* @param context
* @param files
*/
- public WallpaperBackupHelper(Context context, String[] files, String[] keys) {
+ public WallpaperBackupHelper(Context context, String[] keys) {
super(context);
mContext = context;
- mFiles = files;
mKeys = keys;
- final WindowManager wm =
- (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- final WallpaperManager wpm =
- (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
- final Display d = wm.getDefaultDisplay();
- final Point size = new Point();
- d.getSize(size);
- mDesiredMinWidth = Math.min(size.x, size.y);
- mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
- if (mDesiredMinHeight <= 0) {
- mDesiredMinHeight = size.y;
- }
-
- if (DEBUG) {
- Slog.d(TAG, "dmW=" + mDesiredMinWidth + " dmH=" + mDesiredMinHeight);
- }
+ mWpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
}
/**
@@ -126,13 +76,12 @@
@Override
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) {
- performBackup_checked(oldState, data, newState, mFiles, mKeys);
+ // Intentionally no-op; we don't back up the wallpaper this way any more.
}
/**
* Restore one absolute file entity from the restore stream. If we're restoring the
- * magic wallpaper file, take specific action to determine whether it is suitable for
- * the current device.
+ * magic wallpaper file, apply it as the system wallpaper.
*/
@Override
public void restoreEntity(BackupDataInputStream data) {
@@ -140,69 +89,21 @@
if (isKeyInList(key, mKeys)) {
if (key.equals(WALLPAPER_IMAGE_KEY)) {
// restore the file to the stage for inspection
- File f = new File(STAGE_FILE);
- if (writeFile(f, data)) {
-
- // Preflight the restored image's dimensions without loading it
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(STAGE_FILE, options);
-
- if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
- + " h=" + options.outHeight);
-
- if (REJECT_OUTSIZED_RESTORE) {
- // We accept any wallpaper that is at least as wide as our preference
- // (i.e. wide enough to fill the screen), and is within a comfortable
- // factor of the target height, to avoid significant clipping/scaling/
- // letterboxing. At this point we know that mDesiredMinWidth is the
- // smallest dimension, regardless of current orientation, so we can
- // safely require that the candidate's width and height both exceed
- // that hard minimum.
- final double heightRatio = mDesiredMinHeight / options.outHeight;
- if (options.outWidth < mDesiredMinWidth
- || options.outHeight < mDesiredMinWidth
- || heightRatio >= MAX_HEIGHT_RATIO
- || heightRatio <= MIN_HEIGHT_RATIO) {
- // Not wide enough for the screen, or too short/tall to be a good fit
- // for the height of the screen, broken image file, or the system's
- // desires for wallpaper size are in a bad state. Probably one of the
- // first two.
- Slog.i(TAG, "Restored image dimensions (w="
- + options.outWidth + ", h=" + options.outHeight
- + ") too far off target (tw="
- + mDesiredMinWidth + ", th=" + mDesiredMinHeight
- + "); falling back to default wallpaper.");
- f.delete();
- return;
+ File stage = new File(STAGE_FILE);
+ try {
+ if (writeFile(stage, data)) {
+ try (FileInputStream in = new FileInputStream(stage)) {
+ mWpm.setStream(in);
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to set restored wallpaper: " + e.getMessage());
}
+ } else {
+ Slog.e(TAG, "Unable to save restored wallpaper");
}
-
- // We passed the acceptable-dimensions test (if any), so we're going to
- // use the restored image. That comes last, when we are done restoring
- // both the pixels and the metadata.
+ } finally {
+ stage.delete();
}
- } else if (key.equals(WALLPAPER_INFO_KEY)) {
- // XML file containing wallpaper info
- File f = new File(WALLPAPER_INFO);
- writeFile(f, data);
}
}
}
-
- /**
- * Hook for the agent to call this helper upon completion of the restore. We do this
- * upon completion so that we know both the imagery and the wallpaper info have
- * been emplaced without requiring either or relying on ordering.
- */
- public void onRestoreFinished() {
- final File f = new File(STAGE_FILE);
- if (f.exists()) {
- // TODO: spin a service to copy the restored image to sd/usb storage,
- // since it does not exist anywhere other than the private wallpaper
- // file.
- Slog.d(TAG, "Applying restored wallpaper image.");
- f.renameTo(new File(WALLPAPER_ORIG_IMAGE));
- }
- }
}
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index 7c68079..3d187ec 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -119,8 +119,7 @@
* could be reclaimed by the system.
* <p>
* Apps making logical decisions about disk space should always use
- * {@link StorageManager#getAllocatableBytes(UUID, int)} instead of this
- * value.
+ * {@link StorageManager#getAllocatableBytes(UUID)} instead of this value.
*
* @param storageUuid the UUID of the storage volume you're interested in,
* such as {@link StorageManager#UUID_DEFAULT}.
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 1eac395..e3bc78e 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -205,7 +205,8 @@
}
synchronized (mLeScanClients) {
if (callback != null && mLeScanClients.containsKey(callback)) {
- postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+ return postCallbackErrorOrReturn(callback,
+ ScanCallback.SCAN_FAILED_ALREADY_STARTED);
}
IBluetoothGatt gatt;
try {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 076deab..b2952aa 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -113,8 +113,8 @@
*
* <p>If your app needs to be excluded from battery optimizations (run in the background)
* or to have unrestricted data access (use data in the background) you can declare that
- * you use the {@link android.Manifest.permission#RUN_IN_BACKGROUND} and {@link
- * android.Manifest.permission#USE_DATA_IN_BACKGROUND} respectively. Note that these
+ * you use the {@link android.Manifest.permission#REQUEST_COMPANION_RUN_IN_BACKGROUND} and {@link
+ * android.Manifest.permission#REQUEST_COMPANION_USE_DATA_IN_BACKGROUND} respectively. Note that these
* special capabilities have a negative effect on the device's battery and user's data
* usage, therefore you should requested them when absolutely necessary.</p>
*
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index f907721..58a9183 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -338,7 +338,7 @@
* before they system will consider them non-responsive and ANR the app. Since these usually
* execute on the app's main thread, they are already bound by the ~5 second time limit
* of various operations that can happen there (not to mention just avoiding UI jank), so
- * the receive limit is generally not of concern. However, once you use {@goAsync}, though
+ * the receive limit is generally not of concern. However, once you use {@code goAsync}, though
* able to be off the main thread, the broadcast execution limit still applies, and that
* includes the time spent between calling this method and ultimately
* {@link PendingResult#finish() PendingResult.finish()}.</p>
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 64e464c..cdeaea3 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -39,7 +39,6 @@
import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.ICancellationSignal;
-import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
@@ -47,7 +46,6 @@
import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.MathUtils;
import java.io.File;
import java.io.FileDescriptor;
@@ -1047,7 +1045,7 @@
* @param sortOrder How the rows in the cursor should be sorted.
* If {@code null} then the provider is free to define the sort order.
* @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if none.
- * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * If the operation is canceled, then {@link android.os.OperationCanceledException} will be thrown
* when the query is executed.
* @return a Cursor or {@code null}.
*/
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index daeb987..9623da3 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1535,6 +1535,22 @@
public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
/**
+ * Activity Action: Activity to handle split installation failures.
+ * <p>Splits may be installed dynamically. This happens when an Activity is launched,
+ * but the split that contains the application isn't installed. When a split is
+ * installed in this manner, the containing package usually doesn't know this is
+ * happening. However, if an error occurs during installation, the containing
+ * package can define a single activity handling this action to deal with such
+ * failures.
+ * <p>The activity handling this action must be in the base package.
+ * <p>
+ * Input: {@link #EXTRA_INTENT} the original intent that started split installation.
+ * {@link #EXTRA_SPLIT_NAME} the name of the split that failed to be installed.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
+
+ /**
* @hide
* @deprecated Do not use. This will go away.
* Replace with {@link #ACTION_INSTALL_INSTANT_APP_PACKAGE}.
@@ -1823,9 +1839,7 @@
* <p>
* Type: String
* </p>
- * @hide
*/
- @SystemApi
public static final String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
/**
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index fec2847..ca5fa6b 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -780,26 +780,6 @@
* constant starts at the high bits.
*/
public static final int CONFIG_FONT_SCALE = 0x40000000;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the rotation. Set from the
- * {@link android.R.attr#configChanges} attribute. This is
- * not a core resource configuration, but a higher-level value, so its
- * constant starts at the high bits.
- * @hide We do not want apps to handle this. It will eventually be moved out of
- * {@link Configuration}.
- */
- public static final int CONFIG_ROTATION = 0x20000000;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the app bounds. Set from the
- * {@link android.R.attr#configChanges} attribute. This is
- * not a core resource configuration, but a higher-level value, so its
- * constant starts at the high bits.
- * @hide We do not want apps to handle this. It will eventually be moved out of
- * {@link Configuration}.
- */
- public static final int CONFIG_APP_BOUNDS = 0x10000000;
/** @hide
* Unfortunately the constants for config changes in native code are
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0bfe567..72075a5 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -572,7 +572,7 @@
public static final int PRIVATE_FLAG_STATIC_SHARED_LIBRARY = 1 << 14;
/**
- * Value for {@linl #privateFlags}: When set, the application will only have its splits loaded
+ * Value for {@link #privateFlags}: When set, the application will only have its splits loaded
* if they are required to load a component. Splits can be loaded on demand using the
* {@link Context#createContextForSplit(String)} API.
* @hide
@@ -580,10 +580,40 @@
public static final int PRIVATE_FLAG_ISOLATED_SPLIT_LOADING = 1 << 15;
/**
- * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
- * {@hide}
+ * Value for {@link #privateFlags}: When set, the application was installed as
+ * a virtual preload.
+ * @hide
*/
- public int privateFlags;
+ public static final int PRIVATE_FLAG_VIRTUAL_PRELOAD = 1 << 16;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = {
+ PRIVATE_FLAG_HIDDEN,
+ PRIVATE_FLAG_CANT_SAVE_STATE,
+ PRIVATE_FLAG_FORWARD_LOCK,
+ PRIVATE_FLAG_PRIVILEGED,
+ PRIVATE_FLAG_HAS_DOMAIN_URLS,
+ PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE,
+ PRIVATE_FLAG_DIRECT_BOOT_AWARE,
+ PRIVATE_FLAG_INSTANT,
+ PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE,
+ PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
+ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE,
+ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE,
+ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION,
+ PRIVATE_FLAG_BACKUP_IN_FOREGROUND,
+ PRIVATE_FLAG_STATIC_SHARED_LIBRARY,
+ PRIVATE_FLAG_ISOLATED_SPLIT_LOADING,
+ PRIVATE_FLAG_VIRTUAL_PRELOAD,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ApplicationInfoPrivateFlags {}
+
+ /**
+ * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
+ * @hide
+ */
+ public @ApplicationInfoPrivateFlags int privateFlags;
/**
* @hide
@@ -1509,6 +1539,13 @@
}
/**
+ * Returns whether or not this application was installed as a virtual preload.
+ */
+ public boolean isVirtualPreload() {
+ return (privateFlags & PRIVATE_FLAG_VIRTUAL_PRELOAD) != 0;
+ }
+
+ /**
* @hide
*/
@Override protected ApplicationInfo getApplicationInfo() {
diff --git a/core/java/android/content/pm/AuxiliaryResolveInfo.java b/core/java/android/content/pm/AuxiliaryResolveInfo.java
index 323733c..067363d 100644
--- a/core/java/android/content/pm/AuxiliaryResolveInfo.java
+++ b/core/java/android/content/pm/AuxiliaryResolveInfo.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -35,6 +36,8 @@
public final InstantAppResolveInfo resolveInfo;
/** The resolved package. Copied from {@link #resolveInfo}. */
public final String packageName;
+ /** The activity to launch if there's an installation failure. */
+ public final ComponentName installFailureActivity;
/** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
public final String splitName;
/** Whether or not instant resolution needs the second phase */
@@ -61,15 +64,18 @@
this.needsPhaseTwo = needsPhase2;
this.versionCode = resolveInfo.getVersionCode();
this.failureIntent = failureIntent;
+ this.installFailureActivity = null;
}
/** Create a response for installing a split on demand. */
public AuxiliaryResolveInfo(@NonNull String packageName,
@Nullable String splitName,
+ @Nullable ComponentName failureActivity,
int versionCode,
@Nullable Intent failureIntent) {
super();
this.packageName = packageName;
+ this.installFailureActivity = failureActivity;
this.splitName = splitName;
this.versionCode = versionCode;
this.resolveInfo = null;
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 2a3fac3..0b16852 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -32,6 +32,7 @@
void removeSplit(String splitName);
void close();
- void commit(in IntentSender statusReceiver);
+ void commit(in IntentSender statusReceiver, boolean forTransferred);
+ void transfer(in String packageName);
void abandon();
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 9b795aa..0e70645 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -72,7 +72,7 @@
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
- PermissionInfo getPermissionInfo(String name, int flags);
+ PermissionInfo getPermissionInfo(String name, String packageName, int flags);
ParceledListSlice queryPermissionsByGroup(String group, int flags);
@@ -128,6 +128,7 @@
String[] getPackagesForUid(int uid);
String getNameForUid(int uid);
+ String[] getNamesForUids(in int[] uids);
int getUidForSharedUser(String sharedUserName);
@@ -469,11 +470,19 @@
* Notify the package manager that a list of dex files have been loaded.
*
* @param loadingPackageName the name of the package who performs the load
- * @param dexPats the list of the dex files paths that have been loaded
+ * @param classLoadersNames the names of the class loaders present in the loading chain. The
+ * list encodes the class loader chain in the natural order. The first class loader has
+ * the second one as its parent and so on. The dex files present in the class path of the
+ * first class loader will be recorded in the usage file.
+ * @param classPaths the class paths corresponding to the class loaders names from
+ * {@param classLoadersNames}. The the first element corresponds to the first class loader
+ * and so on. A classpath is represented as a list of dex files separated by
+ * {@code File.pathSeparator}.
+ * The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the loader process
*/
- oneway void notifyDexLoad(String loadingPackageName, in List<String> dexPaths,
- String loaderIsa);
+ oneway void notifyDexLoad(String loadingPackageName, in List<String> classLoadersNames,
+ in List<String> classPaths, String loaderIsa);
/**
* Register an application dex module with the package manager.
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index ea675fb..f4fdcaa 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -38,6 +38,7 @@
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.system.ErrnoException;
@@ -793,7 +794,7 @@
* @throws IOException if trouble opening the file for writing, such as
* lack of disk space or unavailable media.
* @throws SecurityException if called after the session has been
- * committed or abandoned.
+ * sealed or abandoned
*/
public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes,
long lengthBytes) throws IOException {
@@ -918,7 +919,68 @@
*/
public void commit(@NonNull IntentSender statusReceiver) {
try {
- mSession.commit(statusReceiver);
+ mSession.commit(statusReceiver, false);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Attempt to commit a session that has been {@link #transfer(String) transferred}.
+ *
+ * <p>If the device reboots before the session has been finalized, you may commit the
+ * session again.
+ *
+ * <p>The caller of this method is responsible to ensure the safety of the session. As the
+ * session was created by another - usually less trusted - app, it is paramount that before
+ * committing <u>all</u> public and system {@link SessionInfo properties of the session}
+ * and <u>all</u> {@link #openRead(String) APKs} are verified by the caller. It might happen
+ * that new properties are added to the session with a new API revision. In this case the
+ * callers need to be updated.
+ *
+ * @param statusReceiver Callbacks called when the state of the session changes.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES)
+ public void commitTransferred(@NonNull IntentSender statusReceiver) {
+ try {
+ mSession.commit(statusReceiver, true);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Transfer the session to a new owner.
+ * <p>
+ * Only sessions that update the installing app can be transferred.
+ * <p>
+ * After the transfer to a package with a different uid all method calls on the session
+ * will cause {@link SecurityException}s.
+ * <p>
+ * Once this method is called, the session is sealed and no additional mutations beside
+ * committing it may be performed on the session.
+ *
+ * @param packageName The package of the new owner. Needs to hold the INSTALL_PACKAGES
+ * permission.
+ *
+ * @throws PackageManager.NameNotFoundException if the new owner could not be found.
+ * @throws SecurityException if called after the session has been committed or abandoned.
+ * @throws SecurityException if the session does not update the original installer
+ * @throws SecurityException if streams opened through
+ * {@link #openWrite(String, long, long) are still open.
+ */
+ public void transfer(@NonNull String packageName)
+ throws PackageManager.NameNotFoundException {
+ Preconditions.checkNotNull(packageName);
+
+ try {
+ mSession.transfer(packageName);
+ } catch (ParcelableException e) {
+ e.maybeRethrow(PackageManager.NameNotFoundException.class);
+ throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1041,6 +1103,26 @@
}
/**
+ * Check if there are hidden options set.
+ *
+ * <p>Hidden options are those options that cannot be verified via public or system-api
+ * methods on {@link SessionInfo}.
+ *
+ * @return {@code true} if any hidden option is set.
+ *
+ * @hide
+ */
+ public boolean areHiddenOptionsSet() {
+ return (installFlags & (PackageManager.INSTALL_ALLOW_DOWNGRADE
+ | PackageManager.INSTALL_DONT_KILL_APP
+ | PackageManager.INSTALL_INSTANT_APP
+ | PackageManager.INSTALL_FULL_APP
+ | PackageManager.INSTALL_VIRTUAL_PRELOAD
+ | PackageManager.INSTALL_ALLOCATE_AGGRESSIVE)) != installFlags
+ || abiOverride != null || volumeUuid != null;
+ }
+
+ /**
* Provide value of {@link PackageInfo#installLocation}, which may be used
* to determine where the app will be staged. Defaults to
* {@link PackageInfo#INSTALL_LOCATION_INTERNAL_ONLY}.
@@ -1300,6 +1382,19 @@
public CharSequence appLabel;
/** {@hide} */
+ public int installLocation;
+ /** {@hide} */
+ public Uri originatingUri;
+ /** {@hide} */
+ public int originatingUid;
+ /** {@hide} */
+ public Uri referrerUri;
+ /** {@hide} */
+ public String[] grantedRuntimePermissions;
+ /** {@hide} */
+ public int installFlags;
+
+ /** {@hide} */
public SessionInfo() {
}
@@ -1318,6 +1413,13 @@
appPackageName = source.readString();
appIcon = source.readParcelable(null);
appLabel = source.readString();
+
+ installLocation = source.readInt();
+ originatingUri = source.readParcelable(null);
+ originatingUid = source.readInt();
+ referrerUri = source.readParcelable(null);
+ grantedRuntimePermissions = source.readStringArray();
+ installFlags = source.readInt();
}
/**
@@ -1406,8 +1508,9 @@
// Icon may have been omitted for calls that return bulk session
// lists, so try fetching the specific icon.
try {
- appIcon = AppGlobals.getPackageManager().getPackageInstaller()
- .getSessionInfo(sessionId).appIcon;
+ final SessionInfo info = AppGlobals.getPackageManager().getPackageInstaller()
+ .getSessionInfo(sessionId);
+ appIcon = (info != null) ? info.appIcon : null;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1440,6 +1543,130 @@
return intent;
}
+ /**
+ * Get the mode of the session as set in the constructor of the {@link SessionParams}.
+ *
+ * @return One of {@link SessionParams#MODE_FULL_INSTALL}
+ * or {@link SessionParams#MODE_INHERIT_EXISTING}
+ */
+ public int getMode() {
+ return mode;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setInstallLocation(int)}.
+ */
+ public int getInstallLocation() {
+ return installLocation;
+ }
+
+ /**
+ * Get the value as set in {@link SessionParams#setSize(long)}.
+ *
+ * <p>The value is a hint and does not have to match the actual size.
+ */
+ public long getSize() {
+ return sizeBytes;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setOriginatingUri(Uri)}.
+ */
+ public @Nullable Uri getOriginatingUri() {
+ return originatingUri;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setOriginatingUid(int)}.
+ */
+ public int getOriginatingUid() {
+ return originatingUid;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setReferrerUri(Uri)}
+ */
+ public @Nullable Uri getReferrerUri() {
+ return referrerUri;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setGrantedRuntimePermissions(String[])}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public @Nullable String[] getGrantedRuntimePermissions() {
+ return grantedRuntimePermissions;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setAllowDowngrade(boolean)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean getAllowDowngrade() {
+ return (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setDontKillApp(boolean)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean getDontKillApp() {
+ return (installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0;
+ }
+
+ /**
+ * If {@link SessionParams#setInstallAsInstantApp(boolean)} was called with {@code true},
+ * return true. If it was called with {@code false} or if it was not called return false.
+ *
+ * @hide
+ *
+ * @see #getInstallAsFullApp
+ */
+ @SystemApi
+ public boolean getInstallAsInstantApp(boolean isInstantApp) {
+ return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+ }
+
+ /**
+ * If {@link SessionParams#setInstallAsInstantApp(boolean)} was called with {@code false},
+ * return true. If it was called with {@code true} or if it was not called return false.
+ *
+ * @hide
+ *
+ * @see #getInstallAsInstantApp
+ */
+ @SystemApi
+ public boolean getInstallAsFullApp(boolean isInstantApp) {
+ return (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
+ }
+
+ /**
+ * Get if {@link SessionParams#setInstallAsVirtualPreload()} was called.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean getInstallAsVirtualPreload() {
+ return (installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0;
+ }
+
+ /**
+ * Get the value set in {@link SessionParams#setAllocateAggressive(boolean)}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean getAllocateAggressive() {
+ return (installFlags & PackageManager.INSTALL_ALLOCATE_AGGRESSIVE) != 0;
+ }
+
+
/** {@hide} */
@Deprecated
public @Nullable Intent getDetailsIntent() {
@@ -1466,6 +1693,13 @@
dest.writeString(appPackageName);
dest.writeParcelable(appIcon, flags);
dest.writeString(appLabel != null ? appLabel.toString() : null);
+
+ dest.writeInt(installLocation);
+ dest.writeParcelable(originatingUri, flags);
+ dest.writeInt(originatingUid);
+ dest.writeParcelable(referrerUri, flags);
+ dest.writeStringArray(grantedRuntimePermissions);
+ dest.writeInt(installFlags);
}
public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cc197a2..f6eaed4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3590,6 +3590,14 @@
public abstract @Nullable String getNameForUid(int uid);
/**
+ * Retrieves the official names associated with each given uid.
+ * @see #getNameForUid(int)
+ *
+ * @hide
+ */
+ public abstract @Nullable String[] getNamesForUids(int[] uids);
+
+ /**
* Return the user id associated with a shared user name. Multiple
* applications can specify a shared user name in their manifest and thus
* end up using a common uid. This might be used for new applications
@@ -4021,6 +4029,7 @@
* @hide
*/
@SystemApi
+ @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent,
@ResolveInfoFlags int flags, UserHandle userHandle) {
return queryBroadcastReceiversAsUser(intent, flags, userHandle.getIdentifier());
@@ -4809,6 +4818,7 @@
* @hide
*/
@SystemApi
+ @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public abstract int getIntentVerificationStatusAsUser(String packageName, @UserIdInt int userId);
/**
@@ -4878,6 +4888,7 @@
*/
@TestApi
@SystemApi
+ @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public abstract String getDefaultBrowserPackageNameAsUser(@UserIdInt int userId);
/**
@@ -4893,7 +4904,9 @@
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
+ @RequiresPermission(allOf = {
+ Manifest.permission.SET_PREFERRED_APPLICATIONS,
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL})
public abstract boolean setDefaultBrowserPackageNameAsUser(String packageName,
@UserIdInt int userId);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 69e3369..b6ed95a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -50,6 +50,8 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageParserCacheHelper.ReadHelper;
+import android.content.pm.PackageParserCacheHelper.WriteHelper;
import android.content.pm.split.DefaultSplitAssetLoader;
import android.content.pm.split.SplitAssetDependencyLoader;
import android.content.pm.split.SplitAssetLoader;
@@ -64,6 +66,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PatternMatcher;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
@@ -120,6 +123,7 @@
import java.util.List;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry;
@@ -145,6 +149,8 @@
private static final boolean DEBUG_JAR = false;
private static final boolean DEBUG_PARSER = false;
private static final boolean DEBUG_BACKUP = false;
+ private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE;
+ private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;
private static final String PROPERTY_CHILD_PACKAGES_ENABLED =
"persist.sys.child_packages_enabled";
@@ -232,6 +238,11 @@
private static final boolean LOG_UNSAFE_BROADCASTS = false;
+ /**
+ * Total number of packages that were read from the cache. We use it only for logging.
+ */
+ public static final AtomicInteger sCachedPackageReadCount = new AtomicInteger();
+
// Set of broadcast actions that are safe for manifest receivers
private static final Set<String> SAFE_BROADCASTS = new ArraySet<>();
static {
@@ -993,14 +1004,23 @@
return parsed;
}
+ long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
if (packageFile.isDirectory()) {
parsed = parseClusterPackage(packageFile, flags);
} else {
parsed = parseMonolithicPackage(packageFile, flags);
}
+ long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
cacheResult(packageFile, flags, parsed);
-
+ if (LOG_PARSE_TIMINGS) {
+ parseTime = cacheTime - parseTime;
+ cacheTime = SystemClock.uptimeMillis() - cacheTime;
+ if (parseTime + cacheTime > LOG_PARSE_TIMINGS_THRESHOLD_MS) {
+ Slog.i(TAG, "Parse times for '" + packageFile + "': parse=" + parseTime
+ + "ms, update_cache=" + cacheTime + " ms");
+ }
+ }
return parsed;
}
@@ -1023,21 +1043,45 @@
}
@VisibleForTesting
- protected Package fromCacheEntry(byte[] bytes) throws IOException {
- Parcel p = Parcel.obtain();
+ protected Package fromCacheEntry(byte[] bytes) {
+ return fromCacheEntryStatic(bytes);
+ }
+
+ /** static version of {@link #fromCacheEntry} for unit tests. */
+ @VisibleForTesting
+ public static Package fromCacheEntryStatic(byte[] bytes) {
+ final Parcel p = Parcel.obtain();
p.unmarshall(bytes, 0, bytes.length);
p.setDataPosition(0);
+ final ReadHelper helper = new ReadHelper(p);
+ helper.startAndInstall();
+
PackageParser.Package pkg = new PackageParser.Package(p);
+
p.recycle();
+ sCachedPackageReadCount.incrementAndGet();
+
return pkg;
}
@VisibleForTesting
- protected byte[] toCacheEntry(Package pkg) throws IOException {
- Parcel p = Parcel.obtain();
+ protected byte[] toCacheEntry(Package pkg) {
+ return toCacheEntryStatic(pkg);
+
+ }
+
+ /** static version of {@link #toCacheEntry} for unit tests. */
+ @VisibleForTesting
+ public static byte[] toCacheEntryStatic(Package pkg) {
+ final Parcel p = Parcel.obtain();
+ final WriteHelper helper = new WriteHelper(p);
+
pkg.writeToParcel(p, 0 /* flags */);
+
+ helper.finishAndUninstall();
+
byte[] serialized = p.marshall();
p.recycle();
@@ -1134,13 +1178,7 @@
}
}
- final byte[] cacheEntry;
- try {
- cacheEntry = toCacheEntry(parsed);
- } catch (IOException ioe) {
- Slog.e(TAG, "Unable to serialize parsed package for: " + packageFile);
- return;
- }
+ final byte[] cacheEntry = toCacheEntry(parsed);
if (cacheEntry == null) {
return;
@@ -2964,7 +3002,7 @@
if (procSeq == null || procSeq.length() <= 0) {
return defProc;
}
- return buildCompoundName(pkg, procSeq, "process", outError);
+ return TextUtils.safeIntern(buildCompoundName(pkg, procSeq, "process", outError));
}
private static String buildTaskAffinityName(String pkg, String defProc,
@@ -6409,8 +6447,11 @@
dest.writeStringList(requestedPermissions);
dest.writeStringList(protectedBroadcasts);
+
+ // TODO: This doesn't work: b/64295061
dest.writeParcelable(parentPackage, flags);
dest.writeParcelableList(childPackages, flags);
+
dest.writeString(staticSharedLibName);
dest.writeInt(staticSharedLibVersion);
dest.writeStringList(libraryNames);
@@ -6889,6 +6930,11 @@
} else {
ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_INSTANT;
}
+ if (state.virtualPreload) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD;
+ } else {
+ ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD;
+ }
if (state.hidden) {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
} else {
diff --git a/core/java/android/content/pm/PackageParserCacheHelper.java b/core/java/android/content/pm/PackageParserCacheHelper.java
new file mode 100644
index 0000000..44def33
--- /dev/null
+++ b/core/java/android/content/pm/PackageParserCacheHelper.java
@@ -0,0 +1,157 @@
+/*
+ * 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.content.pm;
+
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Helper classes to read from and write to Parcel with pooled strings.
+ *
+ * @hide
+ */
+public class PackageParserCacheHelper {
+ private PackageParserCacheHelper() {
+ }
+
+ private static final String TAG = "PackageParserCacheHelper";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Parcel read helper with a string pool.
+ */
+ public static class ReadHelper extends Parcel.ReadWriteHelper {
+ private final ArrayList<String> mStrings = new ArrayList<>();
+
+ private final Parcel mParcel;
+
+ public ReadHelper(Parcel p) {
+ mParcel = p;
+ }
+
+ /**
+ * Prepare to read from a parcel, and install itself as a read-write helper.
+ *
+ * (We don't do it in the constructor to avoid calling methods before the constructor
+ * finishes.)
+ */
+ public void startAndInstall() {
+ mStrings.clear();
+
+ final int poolPosition = mParcel.readInt();
+ final int startPosition = mParcel.dataPosition();
+
+ // The pool is at the end of the parcel.
+ mParcel.setDataPosition(poolPosition);
+ mParcel.readStringList(mStrings);
+
+ // Then move back.
+ mParcel.setDataPosition(startPosition);
+
+ if (DEBUG) {
+ Log.i(TAG, "Read " + mStrings.size() + " strings");
+ for (int i = 0; i < mStrings.size(); i++) {
+ Log.i(TAG, " " + i + ": \"" + mStrings.get(i) + "\"");
+ }
+ }
+
+ mParcel.setReadWriteHelper(this);
+ }
+
+ /**
+ * Read an string index from a parcel, and returns the corresponding string from the pool.
+ */
+ @Override
+ public String readString(Parcel p) {
+ return mStrings.get(p.readInt());
+ }
+ }
+
+ /**
+ * Parcel write helper with a string pool.
+ */
+ public static class WriteHelper extends Parcel.ReadWriteHelper {
+ private final ArrayList<String> mStrings = new ArrayList<>();
+
+ private final HashMap<String, Integer> mIndexes = new HashMap<>();
+
+ private final Parcel mParcel;
+ private final int mStartPos;
+
+ /**
+ * Constructor. Prepare a parcel, and install it self as a read-write helper.
+ */
+ public WriteHelper(Parcel p) {
+ mParcel = p;
+ mStartPos = p.dataPosition();
+ mParcel.writeInt(0); // We come back later here and write the pool position.
+
+ mParcel.setReadWriteHelper(this);
+ }
+
+ /**
+ * Instead of writing a string directly to a parcel, this method adds it to the pool,
+ * and write the index in the pool to the parcel.
+ */
+ @Override
+ public void writeString(Parcel p, String s) {
+ final Integer cur = mIndexes.get(s);
+ if (cur != null) {
+ // String already in the pool. Just write the index.
+ p.writeInt(cur); // Already in the pool.
+ if (DEBUG) {
+ Log.i(TAG, "Duplicate '" + s + "' at " + cur);
+ }
+ } else {
+ // Not in the pool. Add to the pool, and write the index.
+ final int index = mStrings.size();
+ mIndexes.put(s, index);
+ mStrings.add(s);
+
+ if (DEBUG) {
+ Log.i(TAG, "New '" + s + "' at " + index);
+ }
+
+ p.writeInt(index);
+ }
+ }
+
+ /**
+ * Closes a parcel by appending the string pool at the end and updating the pool offset,
+ * which it assumes is at the first byte. It also uninstalls itself as a read-write helper.
+ */
+ public void finishAndUninstall() {
+ // Uninstall first, so that writeStringList() uses the native writeString.
+ mParcel.setReadWriteHelper(null);
+
+ final int poolPosition = mParcel.dataPosition();
+ mParcel.writeStringList(mStrings);
+
+ mParcel.setDataPosition(mStartPos);
+ mParcel.writeInt(poolPosition);
+
+ // Move back to the end.
+ mParcel.setDataPosition(mParcel.dataSize());
+ if (DEBUG) {
+ Log.i(TAG, "Wrote " + mStrings.size() + " strings");
+ }
+ }
+ }
+}
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 470336c..069b2d4 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -21,10 +21,10 @@
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
-import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import android.util.ArraySet;
@@ -45,6 +45,7 @@
public boolean hidden; // Is the app restricted by owner / admin
public boolean suspended;
public boolean instantApp;
+ public boolean virtualPreload;
public int enabled;
public String lastDisableAppCaller;
public int domainVerificationStatus;
@@ -75,6 +76,7 @@
hidden = o.hidden;
suspended = o.suspended;
instantApp = o.instantApp;
+ virtualPreload = o.virtualPreload;
enabled = o.enabled;
lastDisableAppCaller = o.lastDisableAppCaller;
domainVerificationStatus = o.domainVerificationStatus;
@@ -194,6 +196,9 @@
if (instantApp != oldState.instantApp) {
return false;
}
+ if (virtualPreload != oldState.virtualPreload) {
+ return false;
+ }
if (enabled != oldState.enabled) {
return false;
}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 7b96c6a..f7cccd5 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -42,8 +42,6 @@
import java.util.ArrayList;
import java.util.Locale;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_UNDEFINED;
/**
* This class describes all device configuration information that can
@@ -600,13 +598,6 @@
*/
public int orientation;
- /**
- * The mRotation used at the time orientation was determined.
- * TODO(b/36812336): Move mRotation out of {@link Configuration}.
- * {@hide}
- */
- private int mRotation;
-
/** Constant for {@link #uiMode}: bits that encode the mode type. */
public static final int UI_MODE_TYPE_MASK = 0x0f;
/** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
@@ -894,7 +885,6 @@
navigation = o.navigation;
navigationHidden = o.navigationHidden;
orientation = o.orientation;
- mRotation = o.mRotation;
screenLayout = o.screenLayout;
colorMode = o.colorMode;
uiMode = o.uiMode;
@@ -1085,7 +1075,6 @@
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
- mRotation = ROTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_UNDEFINED;
colorMode = COLOR_MODE_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
@@ -1194,11 +1183,6 @@
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
- if (delta.mRotation != ROTATION_UNDEFINED
- && mRotation != delta.mRotation) {
- changed |= ActivityInfo.CONFIG_ORIENTATION;
- mRotation = delta.mRotation;
- }
if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
&& (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
@@ -1334,7 +1318,19 @@
* PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
*/
public int diff(Configuration delta) {
- return diff(delta, false /* compareUndefined */);
+ return diff(delta, false /* compareUndefined */, false /* publicOnly */);
+ }
+
+ /**
+ * Returns the diff against the provided {@link Configuration} excluding values that would
+ * publicly be equivalent, such as appBounds.
+ * @param delta {@link Configuration} to compare to.
+ *
+ * TODO(b/36812336): Remove once appBounds has been moved out of Configuration.
+ * {@hide}
+ */
+ public int diffPublicOnly(Configuration delta) {
+ return diff(delta, false /* compareUndefined */, true /* publicOnly */);
}
/**
@@ -1342,7 +1338,7 @@
*
* @hide
*/
- public int diff(Configuration delta, boolean compareUndefined) {
+ public int diff(Configuration delta, boolean compareUndefined, boolean publicOnly) {
int changed = 0;
if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) {
changed |= ActivityInfo.CONFIG_FONT_SCALE;
@@ -1393,10 +1389,6 @@
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
- if ((compareUndefined || delta.mRotation != ROTATION_UNDEFINED)
- && mRotation != delta.mRotation) {
- changed |= ActivityInfo.CONFIG_ROTATION;
- }
if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
(SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
&& getScreenLayoutNoDirection(screenLayout) !=
@@ -1444,8 +1436,10 @@
// Make sure that one of the values is not null and that they are not equal.
if ((compareUndefined || delta.appBounds != null)
&& appBounds != delta.appBounds
- && (appBounds == null || !appBounds.equals(delta.appBounds))) {
- changed |= ActivityInfo.CONFIG_APP_BOUNDS;
+ && (appBounds == null || (!publicOnly && !appBounds.equals(delta.appBounds))
+ || (publicOnly && (appBounds.width() != delta.appBounds.width()
+ || appBounds.height() != delta.appBounds.height())))) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
}
return changed;
@@ -1533,7 +1527,6 @@
dest.writeInt(navigation);
dest.writeInt(navigationHidden);
dest.writeInt(orientation);
- dest.writeInt(mRotation);
dest.writeInt(screenLayout);
dest.writeInt(colorMode);
dest.writeInt(uiMode);
@@ -1570,7 +1563,6 @@
navigation = source.readInt();
navigationHidden = source.readInt();
orientation = source.readInt();
- mRotation = source.readInt();
screenLayout = source.readInt();
colorMode = source.readInt();
uiMode = source.readInt();
@@ -1655,8 +1647,6 @@
if (n != 0) return n;
n = this.orientation - that.orientation;
if (n != 0) return n;
- n = this.mRotation - that.mRotation;
- if (n != 0) return n;
n = this.colorMode - that.colorMode;
if (n != 0) return n;
n = this.screenLayout - that.screenLayout;
@@ -1805,24 +1795,6 @@
/**
* @hide
*
- * Setter for orientation converts from {@link Surface} values to internal representation.
- */
- public void setRotation(int rotation) {
- this.mRotation = rotation;
- }
-
- /**
- * @hide
- *
- * Getter for orientation. Converts from internal representation to {@link Surface} values.
- */
- public int getRotation() {
- return mRotation != ROTATION_UNDEFINED ? mRotation : ROTATION_0;
- }
-
- /**
- * @hide
- *
* Clears the locale without changing layout direction.
*/
public void clearLocales() {
@@ -2253,10 +2225,6 @@
delta.orientation = change.orientation;
}
- if (base.mRotation != change.mRotation) {
- base.mRotation = change.mRotation;
- }
-
if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
(change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
@@ -2388,8 +2356,6 @@
DENSITY_DPI_UNDEFINED);
configOut.appBounds =
Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
- configOut.mRotation = XmlUtils.readIntAttribute(parser, XML_ATTR_ROTATION,
- ROTATION_UNDEFINED);
// For persistence, we don't care about assetsSeq, so do not read it out.
}
@@ -2466,10 +2432,6 @@
config.appBounds.flattenToString());
}
- if (config.mRotation != ROTATION_UNDEFINED) {
- XmlUtils.writeIntAttribute(xml, XML_ATTR_ROTATION, config.mRotation);
- }
-
// For persistence, we do not care about assetsSeq, so do not write it out.
}
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 581fe7f..fdb702f 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -23,6 +23,7 @@
import android.util.Log;
import java.lang.ref.WeakReference;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -330,7 +331,14 @@
public int getColumnIndexOrThrow(String columnName) {
final int index = getColumnIndex(columnName);
if (index < 0) {
- throw new IllegalArgumentException("column '" + columnName + "' does not exist");
+ String availableColumns = "";
+ try {
+ availableColumns = Arrays.toString(getColumnNames());
+ } catch (Exception e) {
+ Log.d(TAG, "Cannot collect column names for debug purposes", e);
+ }
+ throw new IllegalArgumentException("column '" + columnName
+ + "' does not exist. Available columns: " + availableColumns);
}
return index;
}
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 765f27e..b66bf18 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -16,7 +16,6 @@
package android.database.sqlite;
-import android.app.ActivityManager;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.Handler;
@@ -24,7 +23,6 @@
import android.os.Message;
import android.os.OperationCanceledException;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.util.Log;
import android.util.PrefixPrinter;
import android.util.Printer;
@@ -84,15 +82,6 @@
// and logging a message about the connection pool being busy.
private static final long CONNECTION_POOL_BUSY_MILLIS = 30 * 1000; // 30 seconds
- // TODO b/63398887 Move to SQLiteGlobal
- private static final long IDLE_CONNECTION_CLOSE_DELAY_MILLIS = SystemProperties
- .getInt("persist.debug.sqlite.idle_connection_close_delay", 30000);
-
- // TODO b/63398887 STOPSHIP.
- // Temporarily enabled for testing across a broader set of dogfood devices.
- private static final boolean CLOSE_IDLE_CONNECTIONS = SystemProperties
- .getBoolean("persist.debug.sqlite.close_idle_connections", true);
-
private final CloseGuard mCloseGuard = CloseGuard.get();
private final Object mLock = new Object();
@@ -167,16 +156,12 @@
private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
- // Disable lookaside allocator on low-RAM devices
- if (ActivityManager.isLowRamDeviceStatic()) {
- mConfiguration.lookasideSlotCount = 0;
- mConfiguration.lookasideSlotSize = 0;
- }
setMaxConnectionPoolSizeLocked();
-
- // Do not close idle connections for in-memory databases
- if (CLOSE_IDLE_CONNECTIONS && !configuration.isInMemoryDb()) {
- setupIdleConnectionHandler(Looper.getMainLooper(), IDLE_CONNECTION_CLOSE_DELAY_MILLIS);
+ // If timeout is set, setup idle connection handler
+ // In case of MAX_VALUE - idle connections are never closed
+ if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
+ setupIdleConnectionHandler(Looper.getMainLooper(),
+ mConfiguration.idleConnectionTimeoutMs);
}
}
@@ -214,6 +199,12 @@
// This might throw if the database is corrupt.
mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
true /*primaryConnection*/); // might throw
+ // Mark it released so it can be closed after idle timeout
+ synchronized (mLock) {
+ if (mIdleConnectionHandler != null) {
+ mIdleConnectionHandler.connectionReleased(mAvailablePrimaryConnection);
+ }
+ }
// Mark the pool as being open for business.
mIsOpen = true;
@@ -1009,24 +1000,26 @@
}
private void setMaxConnectionPoolSizeLocked() {
- if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+ if (!mConfiguration.isInMemoryDb()
+ && (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
} else {
- // TODO: We don't actually need to restrict the connection pool size to 1
+ // We don't actually need to always restrict the connection pool size to 1
// for non-WAL databases. There might be reasons to use connection pooling
- // with other journal modes. For now, enabling connection pooling and
- // using WAL are the same thing in the API.
+ // with other journal modes. However, we should always keep pool size of 1 for in-memory
+ // databases since every :memory: db is separate from another.
+ // For now, enabling connection pooling and using WAL are the same thing in the API.
mMaxConnectionPoolSize = 1;
}
}
/**
- * Set up the handler based on the provided looper and delay.
+ * Set up the handler based on the provided looper and timeout.
*/
@VisibleForTesting
- public void setupIdleConnectionHandler(Looper looper, long delayMs) {
+ public void setupIdleConnectionHandler(Looper looper, long timeoutMs) {
synchronized (mLock) {
- mIdleConnectionHandler = new IdleConnectionHandler(looper, delayMs);
+ mIdleConnectionHandler = new IdleConnectionHandler(looper, timeoutMs);
}
}
@@ -1087,6 +1080,10 @@
printer.println(" Lookaside config: sz=" + mConfiguration.lookasideSlotSize
+ " cnt=" + mConfiguration.lookasideSlotCount);
}
+ if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
+ printer.println(
+ " Idle connection timeout: " + mConfiguration.idleConnectionTimeoutMs);
+ }
printer.println(" Available primary connection:");
if (mAvailablePrimaryConnection != null) {
mAvailablePrimaryConnection.dump(indentedPrinter, verbose);
@@ -1153,11 +1150,11 @@
}
private class IdleConnectionHandler extends Handler {
- private final long mDelay;
+ private final long mTimeout;
- IdleConnectionHandler(Looper looper, long delay) {
+ IdleConnectionHandler(Looper looper, long timeout) {
super(looper);
- mDelay = delay;
+ mTimeout = timeout;
}
@Override
@@ -1170,14 +1167,14 @@
if (closeAvailableConnectionLocked(msg.what)) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Closed idle connection " + mConfiguration.label + " " + msg.what
- + " after " + mDelay);
+ + " after " + mTimeout);
}
}
}
}
void connectionReleased(SQLiteConnection con) {
- sendEmptyMessageDelayed(con.getConnectionId(), mDelay);
+ sendEmptyMessageDelayed(con.getConnectionId(), mTimeout);
}
void connectionAcquired(SQLiteConnection con) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index af6df155..de02ee5 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -20,6 +20,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
@@ -30,6 +31,7 @@
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.OperationCanceledException;
+import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -77,21 +79,21 @@
private static final int EVENT_DB_CORRUPT = 75004;
+ // TODO b/63398887 STOPSHIP.
+ // Temporarily enabled for testing across a broader set of dogfood devices.
+ private static final boolean DEBUG_CLOSE_IDLE_CONNECTIONS = SystemProperties
+ .getBoolean("persist.debug.sqlite.close_idle_connections", true);
+
// Stores reference to all databases opened in the current process.
// (The referent Object is not used at this time.)
// INVARIANT: Guarded by sActiveDatabases.
- private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases =
- new WeakHashMap<SQLiteDatabase, Object>();
+ private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = new WeakHashMap<>();
// Thread-local for database sessions that belong to this database.
// Each thread has its own database session.
// INVARIANT: Immutable.
- private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
- @Override
- protected SQLiteSession initialValue() {
- return createSession();
- }
- };
+ private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal
+ .withInitial(this::createSession);
// The optional factory to use when creating new Cursors. May be null.
// INVARIANT: Immutable.
@@ -261,12 +263,29 @@
private SQLiteDatabase(final String path, final int openFlags,
CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
- int lookasideSlotSize, int lookasideSlotCount) {
+ int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs) {
mCursorFactory = cursorFactory;
mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
mConfigurationLocked.lookasideSlotSize = lookasideSlotSize;
mConfigurationLocked.lookasideSlotCount = lookasideSlotCount;
+ // Disable lookaside allocator on low-RAM devices
+ if (ActivityManager.isLowRamDeviceStatic()) {
+ mConfigurationLocked.lookasideSlotCount = 0;
+ mConfigurationLocked.lookasideSlotSize = 0;
+ }
+ long effectiveTimeoutMs = Long.MAX_VALUE;
+ // Never close idle connections for in-memory databases
+ if (!mConfigurationLocked.isInMemoryDb()) {
+ // First, check app-specific value. Otherwise use defaults
+ // -1 in idleConnectionTimeoutMs indicates unset value
+ if (idleConnectionTimeoutMs >= 0) {
+ effectiveTimeoutMs = idleConnectionTimeoutMs;
+ } else if (DEBUG_CLOSE_IDLE_CONNECTIONS) {
+ effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout();
+ }
+ }
+ mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
}
@Override
@@ -684,17 +703,25 @@
/**
* Open the database according to the specified {@link OpenParams parameters}
*
- * @param path to database file to open and/or create
+ * @param path path to database file to open and/or create.
+ * <p><strong>Important:</strong> The file should be constructed either from an absolute path or
+ * by using {@link android.content.Context#getDatabasePath(String)}.
* @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}
* @return the newly opened database
* @throws SQLiteException if the database cannot be opened
*/
- public static SQLiteDatabase openDatabase(@NonNull String path,
+ public static SQLiteDatabase openDatabase(@NonNull File path,
+ @NonNull OpenParams openParams) {
+ return openDatabase(path.getPath(), openParams);
+ }
+
+ private static SQLiteDatabase openDatabase(@NonNull String path,
@NonNull OpenParams openParams) {
Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
openParams.mCursorFactory, openParams.mErrorHandler,
- openParams.mLookasideSlotSize, openParams.mLookasideSlotCount);
+ openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
+ openParams.mIdleConnectionTimeout);
db.open();
return db;
}
@@ -720,7 +747,7 @@
*/
public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
@DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) {
- SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1);
+ SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1);
db.open();
return db;
}
@@ -853,7 +880,8 @@
*
* @param factory an optional factory class that is called to instantiate a
* cursor when query is called
- * @return a SQLiteDatabase object, or null if the database can't be created
+ * @return a SQLiteDatabase instance
+ * @throws SQLiteException if the database cannot be created
*/
@NonNull
public static SQLiteDatabase create(@Nullable CursorFactory factory) {
@@ -869,7 +897,8 @@
* <p>Sets the locale of the database to the the system's current locale.
* Call {@link #setLocale} if you would like something else.</p>
* @param openParams configuration parameters that are used for opening SQLiteDatabase
- * @return a SQLiteDatabase object, or null if the database can't be created
+ * @return a SQLiteDatabase instance
+ * @throws SQLException if the database cannot be created
*/
@NonNull
public static SQLiteDatabase createInMemory(@NonNull OpenParams openParams) {
@@ -2267,14 +2296,17 @@
private final DatabaseErrorHandler mErrorHandler;
private final int mLookasideSlotSize;
private final int mLookasideSlotCount;
+ private long mIdleConnectionTimeout;
private OpenParams(int openFlags, CursorFactory cursorFactory,
- DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount) {
+ DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
+ long idleConnectionTimeout) {
mOpenFlags = openFlags;
mCursorFactory = cursorFactory;
mErrorHandler = errorHandler;
mLookasideSlotSize = lookasideSlotSize;
mLookasideSlotCount = lookasideSlotCount;
+ mIdleConnectionTimeout = idleConnectionTimeout;
}
/**
@@ -2299,7 +2331,7 @@
}
/**
- * Returns flags to control database access mode
+ * Returns flags to control database access mode. Default value is 0.
*
* @see Builder#setOpenFlags(int)
*/
@@ -2330,6 +2362,17 @@
}
/**
+ * Returns maximum number of milliseconds that SQLite connection is allowed to be idle
+ * before it is closed and removed from the pool.
+ * <p>If the value isn't set, the timeout defaults to the system wide timeout
+ *
+ * @return timeout in milliseconds or -1 if the value wasn't set.
+ */
+ public long getIdleConnectionTimeout() {
+ return mIdleConnectionTimeout;
+ }
+
+ /**
* Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with
* {@code this} parameters.
* @hide
@@ -2345,6 +2388,7 @@
public static final class Builder {
private int mLookasideSlotSize = -1;
private int mLookasideSlotCount = -1;
+ private long mIdleConnectionTimeout = -1;
private int mOpenFlags;
private CursorFactory mCursorFactory;
private DatabaseErrorHandler mErrorHandler;
@@ -2474,13 +2518,29 @@
}
/**
+ * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle
+ * before it is closed and removed from the pool.
+ *
+ * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE}
+ * to allow unlimited idle connections.
+ */
+ @NonNull
+ public Builder setIdleConnectionTimeout(
+ @IntRange(from = 0) long idleConnectionTimeoutMs) {
+ Preconditions.checkArgument(idleConnectionTimeoutMs >= 0,
+ "idle connection timeout cannot be negative");
+ mIdleConnectionTimeout = idleConnectionTimeoutMs;
+ return this;
+ }
+
+ /**
* Creates an instance of {@link OpenParams} with the options that were previously set
* on this builder
*/
@NonNull
public OpenParams build() {
return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize,
- mLookasideSlotCount);
+ mLookasideSlotCount, mIdleConnectionTimeout);
}
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 7f09b73..34c9b33 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -94,14 +94,21 @@
*
* <p>If negative, the default lookaside configuration will be used
*/
- public int lookasideSlotSize;
+ public int lookasideSlotSize = -1;
/**
* The total number of lookaside memory slots per database connection
*
* <p>If negative, the default lookaside configuration will be used
*/
- public int lookasideSlotCount;
+ public int lookasideSlotCount = -1;
+
+ /**
+ * The number of milliseconds that SQLite connection is allowed to be idle before it
+ * is closed and removed from the pool.
+ * <p>By default, idle connections are not closed
+ */
+ public long idleConnectionTimeoutMs = Long.MAX_VALUE;
/**
* Creates a database configuration with the required parameters for opening a
@@ -122,8 +129,6 @@
// Set default values for optional parameters.
maxSqlCacheSize = 25;
locale = Locale.getDefault();
- lookasideSlotSize = -1;
- lookasideSlotCount = -1;
}
/**
@@ -164,6 +169,7 @@
customFunctions.addAll(other.customFunctions);
lookasideSlotSize = other.lookasideSlotSize;
lookasideSlotCount = other.lookasideSlotCount;
+ idleConnectionTimeoutMs = other.idleConnectionTimeoutMs;
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 1197331..a921aa3 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -16,13 +16,14 @@
package android.database.sqlite;
-import java.util.ArrayList;
-
+import android.annotation.TestApi;
import android.os.Build;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Printer;
+import java.util.ArrayList;
+
/**
* Provides debugging info about all SQLite databases running in the current process.
*
@@ -117,6 +118,7 @@
/**
* contains statistics about a database
*/
+ @TestApi
public static class DbStats {
/** name of the database */
public String dbName;
@@ -127,7 +129,8 @@
/** the database size */
public long dbSize;
- /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
+ /**
+ * Number of lookaside slots: http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
public int lookaside;
/** statement cache stats: hits/misses/cachesize */
@@ -147,6 +150,7 @@
* return all pager and database stats for the current process.
* @return {@link PagerStats}
*/
+ @TestApi
public static PagerStats getDatabaseInfo() {
PagerStats stats = new PagerStats();
nativeGetPagerStats(stats);
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index 922d11b..571656a 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -124,4 +124,15 @@
com.android.internal.R.integer.db_connection_pool_size));
return Math.max(2, value);
}
+
+ /**
+ * The default number of milliseconds that SQLite connection is allowed to be idle before it
+ * is closed and removed from the pool.
+ */
+ public static int getIdleConnectionTimeout() {
+ return SystemProperties.getInt("debug.sqlite.idle_connection_timeout",
+ Resources.getSystem().getInteger(
+ com.android.internal.R.integer.db_default_idle_connection_timeout));
+ }
+
}
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index c19db82..cc9e0f4 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -195,6 +195,26 @@
}
/**
+ * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle
+ * before it is closed and removed from the pool.
+ *
+ * <p>This method should be called from the constructor of the subclass,
+ * before opening the database
+ *
+ * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE} value
+ * to allow unlimited idle connections.
+ */
+ public void setIdleConnectionTimeout(@IntRange(from = 0) final long idleConnectionTimeoutMs) {
+ synchronized (this) {
+ if (mDatabase != null && mDatabase.isOpen()) {
+ throw new IllegalStateException(
+ "Connection timeout setting cannot be changed after opening the database");
+ }
+ mOpenParamsBuilder.setIdleConnectionTimeout(idleConnectionTimeoutMs);
+ }
+ }
+
+ /**
* Create and/or open a database that will be used for reading and writing.
* The first time this is called, the database will be opened and
* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
@@ -269,12 +289,12 @@
} else if (mName == null) {
db = SQLiteDatabase.createInMemory(mOpenParamsBuilder.build());
} else {
- final String path = mContext.getDatabasePath(mName).getPath();
+ final File filePath = mContext.getDatabasePath(mName);
SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();
try {
- db = SQLiteDatabase.openDatabase(path, params);
+ db = SQLiteDatabase.openDatabase(filePath, params);
// Keep pre-O-MR1 behavior by resetting file permissions to 660
- setFilePermissionsForDb(path);
+ setFilePermissionsForDb(filePath.getPath());
} catch (SQLException ex) {
if (writable) {
throw ex;
@@ -282,7 +302,7 @@
Log.e(TAG, "Couldn't open " + mName
+ " for writing (will try read-only):", ex);
params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
- db = SQLiteDatabase.openDatabase(path, params);
+ db = SQLiteDatabase.openDatabase(filePath, params);
}
}
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 63eedf5..55343a2 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -73,8 +73,10 @@
* Create a request suitable for still image capture. Specifically, this
* means prioritizing image quality over frame rate. These requests would
* commonly be used with the {@link CameraCaptureSession#capture} method.
- * This template is guaranteed to be supported on all camera devices.
- *
+ * This template is guaranteed to be supported on all camera devices except
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+ * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+ * BACKWARD_COMPATIBLE}.
* @see #createCaptureRequest
*/
public static final int TEMPLATE_STILL_CAPTURE = 2;
@@ -84,7 +86,10 @@
* that a stable frame rate is used, and post-processing is set for
* recording quality. These requests would commonly be used with the
* {@link CameraCaptureSession#setRepeatingRequest} method.
- * This template is guaranteed to be supported on all camera devices.
+ * This template is guaranteed to be supported on all camera devices except
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+ * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+ * BACKWARD_COMPATIBLE}.
*
* @see #createCaptureRequest
*/
@@ -98,7 +103,10 @@
* {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
* This template is guaranteed to be supported on all camera devices except
* legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
- * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
+ * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) and
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+ * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+ * BACKWARD_COMPATIBLE}.
*
* @see #createCaptureRequest
*/
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 6825d36..c7654c9 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -412,6 +412,9 @@
// If no sequences are pending, fire #onClosed immediately
mSequenceDrainer.beginDrain();
}
+ if (mInput != null) {
+ mInput.release();
+ }
}
/**
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index a5bf639..8b6f9c1 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -99,11 +99,14 @@
/**
* The {@link FingerprintManager#remove} call failed. Typically this will happen when the
* provided fingerprint id was incorrect.
+ *
+ * @hide
*/
public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6;
/**
* The operation was canceled because the API is locked out due to too many attempts.
+ * This occurs after 5 failed attempts, and lasts for 30 seconds.
*/
public static final int FINGERPRINT_ERROR_LOCKOUT = 7;
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
index 7f470ef..3aaeb50 100644
--- a/core/java/android/hardware/radio/ITuner.aidl
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -68,18 +68,19 @@
Bitmap getImage(int id);
/**
- * @returns {@code true} if the scan was properly scheduled,
+ * @return {@code true} if the scan was properly scheduled,
* {@code false} if the scan feature is unavailable
*/
boolean startBackgroundScan();
/**
- * @returns the list, or null if scan is in progress
+ * @param vendorFilter Vendor-specific filter, must be Map<String, String>
+ * @return the list, or null if scan is in progress
* @throws IllegalArgumentException if invalid arguments are passed
* @throws IllegalStateException if the scan has not been started, client may
* call startBackgroundScan to fix this.
*/
- List<RadioManager.ProgramInfo> getProgramList(String filter);
+ List<RadioManager.ProgramInfo> getProgramList(in Map vendorFilter);
/**
* @throws IllegalStateException if the switch is not supported at current
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
index c3bbaec..6ed171b 100644
--- a/core/java/android/hardware/radio/ITunerCallback.aidl
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -23,7 +23,7 @@
oneway interface ITunerCallback {
void onError(int status);
void onConfigurationChanged(in RadioManager.BandConfig config);
- void onProgramInfoChanged();
+ void onCurrentProgramInfoChanged(in RadioManager.ProgramInfo info);
void onTrafficAnnouncement(boolean active);
void onEmergencyAnnouncement(boolean active);
void onAntennaState(boolean connected);
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index d9e306f..2211cee 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -17,6 +17,7 @@
package android.hardware.radio;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -73,10 +74,8 @@
/** SiriusXM Satellite Radio. */
public static final int PROGRAM_TYPE_SXM = 7;
/** Vendor-specific, not synced across devices. */
- public static final int PROGRAM_TYPE_VENDOR1 = 8;
- public static final int PROGRAM_TYPE_VENDOR2 = 9;
- public static final int PROGRAM_TYPE_VENDOR3 = 10;
- public static final int PROGRAM_TYPE_VENDOR4 = 11;
+ public static final int PROGRAM_TYPE_VENDOR_START = 1000;
+ public static final int PROGRAM_TYPE_VENDOR_END = 1999;
@IntDef(prefix = { "PROGRAM_TYPE_" }, value = {
PROGRAM_TYPE_AM,
PROGRAM_TYPE_FM,
@@ -85,11 +84,8 @@
PROGRAM_TYPE_DAB,
PROGRAM_TYPE_DRMO,
PROGRAM_TYPE_SXM,
- PROGRAM_TYPE_VENDOR1,
- PROGRAM_TYPE_VENDOR2,
- PROGRAM_TYPE_VENDOR3,
- PROGRAM_TYPE_VENDOR4,
})
+ @IntRange(from = PROGRAM_TYPE_VENDOR_START, to = PROGRAM_TYPE_VENDOR_END)
@Retention(RetentionPolicy.SOURCE)
public @interface ProgramType {}
@@ -145,12 +141,12 @@
* Primary identifier for vendor-specific radio technology.
* The value format is determined by a vendor.
*
- * It must not be used in any other programType than VENDORx.
+ * It must not be used in any other programType than corresponding VENDOR
+ * type between VENDOR_START and VENDOR_END (eg. identifier type 1015 must
+ * not be used in any program type other than 1015).
*/
- public static final int IDENTIFIER_TYPE_VENDOR1_PRIMARY = 14;
- public static final int IDENTIFIER_TYPE_VENDOR2_PRIMARY = 15;
- public static final int IDENTIFIER_TYPE_VENDOR3_PRIMARY = 16;
- public static final int IDENTIFIER_TYPE_VENDOR4_PRIMARY = 17;
+ public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_START = PROGRAM_TYPE_VENDOR_START;
+ public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_END = PROGRAM_TYPE_VENDOR_END;
@IntDef(prefix = { "IDENTIFIER_TYPE_" }, value = {
IDENTIFIER_TYPE_AMFM_FREQUENCY,
IDENTIFIER_TYPE_RDS_PI,
@@ -165,11 +161,8 @@
IDENTIFIER_TYPE_DRMO_MODULATION,
IDENTIFIER_TYPE_SXM_SERVICE_ID,
IDENTIFIER_TYPE_SXM_CHANNEL,
- IDENTIFIER_TYPE_VENDOR1_PRIMARY,
- IDENTIFIER_TYPE_VENDOR2_PRIMARY,
- IDENTIFIER_TYPE_VENDOR3_PRIMARY,
- IDENTIFIER_TYPE_VENDOR4_PRIMARY,
})
+ @IntRange(from = IDENTIFIER_TYPE_VENDOR_PRIMARY_START, to = IDENTIFIER_TYPE_VENDOR_PRIMARY_END)
@Retention(RetentionPolicy.SOURCE)
public @interface IdentifierType {}
@@ -207,7 +200,7 @@
/**
* Type of a radio technology.
*
- * @returns program type.
+ * @return program type.
*/
public @ProgramType int getProgramType() {
return mProgramType;
@@ -217,7 +210,7 @@
* Primary program identifier uniquely identifies a station and is used to
* determine equality between two ProgramSelectors.
*
- * @returns primary identifier.
+ * @return primary identifier.
*/
public @NonNull Identifier getPrimaryId() {
return mPrimaryId;
@@ -227,7 +220,7 @@
* Secondary program identifier is not required for tuning, but may make it
* faster or more reliable.
*
- * @returns secondary identifier list, must not be modified.
+ * @return secondary identifier list, must not be modified.
*/
public @NonNull Identifier[] getSecondaryIds() {
return mSecondaryIds;
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index d5b72aa..4f4361f 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -16,8 +16,10 @@
package android.hardware.radio;
+import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
@@ -33,7 +35,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -115,6 +119,25 @@
* @see BandDescriptor */
public static final int REGION_KOREA = 4;
+ private static void writeStringMap(@NonNull Parcel dest, @NonNull Map<String, String> map) {
+ dest.writeInt(map.size());
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ dest.writeString(entry.getKey());
+ dest.writeString(entry.getValue());
+ }
+ }
+
+ private static @NonNull Map<String, String> readStringMap(@NonNull Parcel in) {
+ int size = in.readInt();
+ Map<String, String> map = new HashMap<>();
+ while (size-- > 0) {
+ String key = in.readString();
+ String value = in.readString();
+ map.put(key, value);
+ }
+ return map;
+ }
+
/*****************************************************************************
* Lists properties, options and radio bands supported by a given broadcast radio module.
* Each module has a unique ID used to address it when calling RadioManager APIs.
@@ -136,14 +159,14 @@
private final boolean mIsBgScanSupported;
private final Set<Integer> mSupportedProgramTypes;
private final Set<Integer> mSupportedIdentifierTypes;
- private final String mVendorInfo;
+ @NonNull private final Map<String, String> mVendorInfo;
ModuleProperties(int id, String serviceName, int classId, String implementor,
String product, String version, String serial, int numTuners, int numAudioSources,
boolean isCaptureSupported, BandDescriptor[] bands, boolean isBgScanSupported,
@ProgramSelector.ProgramType int[] supportedProgramTypes,
@ProgramSelector.IdentifierType int[] supportedIdentifierTypes,
- String vendorInfo) {
+ Map<String, String> vendorInfo) {
mId = id;
mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName;
mClassId = classId;
@@ -158,7 +181,7 @@
mIsBgScanSupported = isBgScanSupported;
mSupportedProgramTypes = arrayToSet(supportedProgramTypes);
mSupportedIdentifierTypes = arrayToSet(supportedIdentifierTypes);
- mVendorInfo = vendorInfo;
+ mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
}
private static Set<Integer> arrayToSet(int[] arr) {
@@ -285,17 +308,17 @@
}
/**
- * Opaque vendor-specific string, passed from HAL without changes.
- * Format of this string can vary across vendors.
+ * A map of vendor-specific opaque strings, passed from HAL without changes.
+ * Format of these strings can vary across vendors.
*
* It may be used for extra features, that's not supported by a platform,
- * for example: "preset-slots=6;ultra-hd-capable=false".
+ * for example: preset-slots=6; ultra-hd-capable=false.
*
- * Client application MUST verify vendor/product name from the
- * ModuleProperties class before doing any interpretation of this value.
+ * Keys must be prefixed with unique vendor Java-style namespace,
+ * eg. 'com.somecompany.parameter1'.
*/
- public @NonNull String getVendorInfo() {
- return mVendorInfo == null ? "" : mVendorInfo;
+ public @NonNull Map<String, String> getVendorInfo() {
+ return mVendorInfo;
}
/** List of descriptors for all bands supported by this module.
@@ -325,7 +348,7 @@
mIsBgScanSupported = in.readInt() == 1;
mSupportedProgramTypes = arrayToSet(in.createIntArray());
mSupportedIdentifierTypes = arrayToSet(in.createIntArray());
- mVendorInfo = in.readString();
+ mVendorInfo = readStringMap(in);
}
public static final Parcelable.Creator<ModuleProperties> CREATOR
@@ -355,7 +378,7 @@
dest.writeInt(mIsBgScanSupported ? 1 : 0);
dest.writeIntArray(setToArray(mSupportedProgramTypes));
dest.writeIntArray(setToArray(mSupportedIdentifierTypes));
- dest.writeString(mVendorInfo);
+ writeStringMap(dest, mVendorInfo);
}
@Override
@@ -392,7 +415,7 @@
result = prime * result + (mIsCaptureSupported ? 1 : 0);
result = prime * result + Arrays.hashCode(mBands);
result = prime * result + (mIsBgScanSupported ? 1 : 0);
- result = prime * result + ((mVendorInfo == null) ? 0 : mVendorInfo.hashCode());
+ result = prime * result + mVendorInfo.hashCode();
return result;
}
@@ -438,7 +461,7 @@
return false;
if (mIsBgScanSupported != other.isBackgroundScanningSupported())
return false;
- if (!TextUtils.equals(mVendorInfo, other.mVendorInfo)) return false;
+ if (!mVendorInfo.equals(other.mVendorInfo)) return false;
return true;
}
}
@@ -1322,11 +1345,11 @@
private final int mFlags;
private final int mSignalStrength;
private final RadioMetadata mMetadata;
- private final String mVendorInfo;
+ @NonNull private final Map<String, String> mVendorInfo;
ProgramInfo(@NonNull ProgramSelector selector, boolean tuned, boolean stereo,
boolean digital, int signalStrength, RadioMetadata metadata, int flags,
- String vendorInfo) {
+ Map<String, String> vendorInfo) {
mSelector = selector;
mTuned = tuned;
mStereo = stereo;
@@ -1334,7 +1357,7 @@
mFlags = flags;
mSignalStrength = signalStrength;
mMetadata = metadata;
- mVendorInfo = vendorInfo;
+ mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
}
/**
@@ -1445,17 +1468,17 @@
}
/**
- * Opaque vendor-specific string, passed from HAL without changes.
- * Format of this string can vary across vendors.
+ * A map of vendor-specific opaque strings, passed from HAL without changes.
+ * Format of these strings can vary across vendors.
*
* It may be used for extra features, that's not supported by a platform,
- * for example: "paid-service=true;bitrate=320kbps".
+ * for example: paid-service=true; bitrate=320kbps.
*
- * Client application MUST verify vendor/product name from the
- * ModuleProperties class before doing any interpretation of this value.
+ * Keys must be prefixed with unique vendor Java-style namespace,
+ * eg. 'com.somecompany.parameter1'.
*/
- public @NonNull String getVendorInfo() {
- return mVendorInfo == null ? "" : mVendorInfo;
+ public @NonNull Map<String, String> getVendorInfo() {
+ return mVendorInfo;
}
private ProgramInfo(Parcel in) {
@@ -1470,7 +1493,7 @@
mMetadata = null;
}
mFlags = in.readInt();
- mVendorInfo = in.readString();
+ mVendorInfo = readStringMap(in);
}
public static final Parcelable.Creator<ProgramInfo> CREATOR
@@ -1498,7 +1521,7 @@
mMetadata.writeToParcel(dest, flags);
}
dest.writeInt(mFlags);
- dest.writeString(mVendorInfo);
+ writeStringMap(dest, mVendorInfo);
}
@Override
@@ -1526,7 +1549,7 @@
result = prime * result + mFlags;
result = prime * result + mSignalStrength;
result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode());
- result = prime * result + ((mVendorInfo == null) ? 0 : mVendorInfo.hashCode());
+ result = prime * result + mVendorInfo.hashCode();
return result;
}
@@ -1553,7 +1576,7 @@
return false;
} else if (!mMetadata.equals(other.getMetadata()))
return false;
- if (!TextUtils.equals(mVendorInfo, other.mVendorInfo)) return false;
+ if (!mVendorInfo.equals(other.mVendorInfo)) return false;
return true;
}
}
@@ -1571,6 +1594,7 @@
* <li>{@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails, </li>
* </ul>
*/
+ @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
public int listModules(List<ModuleProperties> modules) {
if (modules == null) {
Log.e(TAG, "the output list must not be empty");
@@ -1611,6 +1635,7 @@
* Can be null if default handler is OK.
* @return a valid {@link RadioTuner} interface in case of success or null in case of error.
*/
+ @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
public RadioTuner openTuner(int moduleId, BandConfig config, boolean withAudio,
RadioTuner.Callback callback, Handler handler) {
if (callback == null) {
@@ -1631,7 +1656,6 @@
Log.e(TAG, "Failed to open tuner");
return null;
}
- halCallback.attachTuner(tuner);
return new TunerAdapter(tuner, config != null ? config.getType() : BAND_INVALID);
}
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index be37cd0..6e8991a 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -23,6 +23,7 @@
import android.os.Handler;
import java.util.List;
+import java.util.Map;
/**
* RadioTuner interface provides methods to control a radio tuner on the device: selecting and
@@ -182,7 +183,7 @@
* The operation is asynchronous and {@link Callback} onProgramInfoChanged() will be called
* when tune completes or onError() when cancelled or on timeout.
*
- * @thows IllegalArgumentException if the provided selector is invalid
+ * @throws IllegalArgumentException if the provided selector is invalid
*/
public abstract void tune(@NonNull ProgramSelector selector);
@@ -270,16 +271,18 @@
/**
* Get the list of discovered radio stations.
*
- * To get the full list, set filter to null or empty string. Otherwise, client application
- * must verify vendor product/name before setting this parameter to anything else.
+ * To get the full list, set filter to null or empty map.
+ * Keys must be prefixed with unique vendor Java-style namespace,
+ * eg. 'com.somecompany.parameter1'.
*
- * @param filter vendor-specific selector for radio stations.
+ * @param vendorFilter vendor-specific selector for radio stations.
* @return a list of radio stations.
* @throws IllegalStateException if the scan is in progress or has not been started,
* startBackgroundScan() call may fix it.
- * @throws IllegalArgumentException if the filter argument is not valid.
+ * @throws IllegalArgumentException if the vendorFilter argument is not valid.
*/
- public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
+ public abstract @NonNull List<RadioManager.ProgramInfo>
+ getProgramList(@Nullable Map<String, String> vendorFilter);
/**
* Checks, if the analog playback is forced, see setAnalogForced.
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index c687537..b621969 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -23,6 +23,7 @@
import android.util.Log;
import java.util.List;
+import java.util.Map;
/**
* Implements the RadioTuner interface by forwarding calls to radio service.
@@ -222,9 +223,10 @@
}
@Override
- public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) {
+ public @NonNull List<RadioManager.ProgramInfo>
+ getProgramList(@Nullable Map<String, String> vendorFilter) {
try {
- return mTuner.getProgramList(filter);
+ return mTuner.getProgramList(vendorFilter);
} catch (RemoteException e) {
throw new RuntimeException("service died", e);
}
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index 00a36c8..ffd5b30f 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
import android.util.Log;
/**
@@ -31,10 +30,6 @@
@NonNull private final RadioTuner.Callback mCallback;
@NonNull private final Handler mHandler;
- private final Object mLock = new Object();
-
- @Nullable private ITuner mTuner;
- boolean mPendingProgramInfoChanged = false;
TunerCallbackAdapter(@NonNull RadioTuner.Callback callback, @Nullable Handler handler) {
mCallback = callback;
@@ -45,14 +40,6 @@
}
}
- public void attachTuner(@NonNull ITuner tuner) {
- synchronized (mLock) {
- if (mTuner != null) throw new IllegalStateException();
- mTuner = tuner;
- if (mPendingProgramInfoChanged) onProgramInfoChanged();
- }
- }
-
@Override
public void onError(int status) {
mHandler.post(() -> mCallback.onError(status));
@@ -64,19 +51,9 @@
}
@Override
- public void onProgramInfoChanged() {
- synchronized (mLock) {
- if (mTuner == null) {
- mPendingProgramInfoChanged = true;
- return;
- }
- }
-
- RadioManager.ProgramInfo info;
- try {
- info = mTuner.getProgramInformation();
- } catch (RemoteException e) {
- Log.e(TAG, "service died", e);
+ public void onCurrentProgramInfoChanged(RadioManager.ProgramInfo info) {
+ if (info == null) {
+ Log.e(TAG, "ProgramInfo must not be null");
return;
}
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index ed223d1..d2e3510 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -16,10 +16,6 @@
package android.inputmethodservice;
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.view.IInputMethodSession;
-
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
@@ -34,9 +30,13 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.InputMethodSession;
-import android.view.inputmethod.CursorAnchorInfo;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.view.IInputMethodSession;
class IInputMethodSessionWrapper extends IInputMethodSession.Stub
implements HandlerCaller.Callback {
@@ -218,7 +218,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
if (mInputMethodSession == null) {
// The session has been finished.
finishInputEvent(event, false);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 305cf76..0b92893 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -24,6 +24,7 @@
import com.android.internal.util.Preconditions;
import java.util.Objects;
+import java.util.StringJoiner;
/**
* This class represents the capabilities of a network. This is used both to specify
@@ -347,11 +348,6 @@
return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
}
- private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) {
- return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) ==
- (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES));
- }
-
private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) {
return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
(that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
@@ -502,10 +498,12 @@
private void combineTransportTypes(NetworkCapabilities nc) {
this.mTransportTypes |= nc.mTransportTypes;
}
+
private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
return ((this.mTransportTypes == 0) ||
((this.mTransportTypes & nc.mTransportTypes) != 0));
}
+
/** @hide */
public boolean equalsTransportTypes(NetworkCapabilities nc) {
return (nc.mTransportTypes == this.mTransportTypes);
@@ -760,15 +758,43 @@
/**
* Checks that our immutable capabilities are the same as those of the given
- * {@code NetworkCapabilities}.
+ * {@code NetworkCapabilities} and return a String describing any difference.
+ * The returned String is empty if there is no difference.
*
* @hide
*/
- public boolean equalImmutableCapabilities(NetworkCapabilities nc) {
- if (nc == null) return false;
- return (equalsNetCapabilitiesImmutable(nc) &&
- equalsTransportTypes(nc) &&
- equalsSpecifier(nc));
+ public String describeImmutableDifferences(NetworkCapabilities that) {
+ if (that == null) {
+ return "other NetworkCapabilities was null";
+ }
+
+ StringJoiner joiner = new StringJoiner(", ");
+
+ // TODO: consider only enforcing that capabilities are not removed, allowing addition.
+ // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
+ // TODO: properly support NOT_METERED as a mutable and requestable capability.
+ final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
+ long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
+ long newImmutableCapabilities = that.mNetworkCapabilities & mask;
+ if (oldImmutableCapabilities != newImmutableCapabilities) {
+ String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities));
+ String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities));
+ joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
+ }
+
+ if (!equalsSpecifier(that)) {
+ NetworkSpecifier before = this.getNetworkSpecifier();
+ NetworkSpecifier after = that.getNetworkSpecifier();
+ joiner.add(String.format("specifier changed: %s -> %s", before, after));
+ }
+
+ if (!equalsTransportTypes(that)) {
+ String before = transportNamesOf(this.getTransportTypes());
+ String after = transportNamesOf(that.getTransportTypes());
+ joiner.add(String.format("transports changed: %s -> %s", before, after));
+ }
+
+ return joiner.toString();
}
/**
@@ -843,33 +869,15 @@
@Override
public String toString() {
+ // TODO: enumerate bits for transports and capabilities instead of creating arrays.
+ // TODO: use a StringBuilder instead of string concatenation.
int[] types = getTransportTypes();
String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
types = getCapabilities();
String capabilities = (types.length > 0 ? " Capabilities: " : "");
for (int i = 0; i < types.length; ) {
- switch (types[i]) {
- case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
- case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
- case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
- case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
- case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
- case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
- case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
- case NET_CAPABILITY_IA: capabilities += "IA"; break;
- case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
- case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
- case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
- case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
- case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
- case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
- case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break;
- case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break;
- case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break;
- case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break;
- case NET_CAPABILITY_FOREGROUND: capabilities += "FOREGROUND"; break;
- }
+ capabilities += capabilityNameOf(types[i]);
if (++i < types.length) capabilities += "&";
}
@@ -889,15 +897,55 @@
/**
* @hide
*/
+ public static String capabilityNamesOf(int[] capabilities) {
+ StringJoiner joiner = new StringJoiner("|");
+ if (capabilities != null) {
+ for (int c : capabilities) {
+ joiner.add(capabilityNameOf(c));
+ }
+ }
+ return joiner.toString();
+ }
+
+ /**
+ * @hide
+ */
+ public static String capabilityNameOf(int capability) {
+ switch (capability) {
+ case NET_CAPABILITY_MMS: return "MMS";
+ case NET_CAPABILITY_SUPL: return "SUPL";
+ case NET_CAPABILITY_DUN: return "DUN";
+ case NET_CAPABILITY_FOTA: return "FOTA";
+ case NET_CAPABILITY_IMS: return "IMS";
+ case NET_CAPABILITY_CBS: return "CBS";
+ case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P";
+ case NET_CAPABILITY_IA: return "IA";
+ case NET_CAPABILITY_RCS: return "RCS";
+ case NET_CAPABILITY_XCAP: return "XCAP";
+ case NET_CAPABILITY_EIMS: return "EIMS";
+ case NET_CAPABILITY_NOT_METERED: return "NOT_METERED";
+ case NET_CAPABILITY_INTERNET: return "INTERNET";
+ case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED";
+ case NET_CAPABILITY_TRUSTED: return "TRUSTED";
+ case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
+ case NET_CAPABILITY_VALIDATED: return "VALIDATED";
+ case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
+ case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
+ default: return Integer.toString(capability);
+ }
+ }
+
+ /**
+ * @hide
+ */
public static String transportNamesOf(int[] types) {
- if (types == null || types.length == 0) {
- return "";
+ StringJoiner joiner = new StringJoiner("|");
+ if (types != null) {
+ for (int t : types) {
+ joiner.add(transportNameOf(t));
+ }
}
- StringBuilder transports = new StringBuilder();
- for (int t : types) {
- transports.append("|").append(transportNameOf(t));
- }
- return transports.substring(1);
+ return joiner.toString();
}
/**
diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java
index fdb4ba0..a70c97b 100644
--- a/core/java/android/net/NetworkRecommendationProvider.java
+++ b/core/java/android/net/NetworkRecommendationProvider.java
@@ -35,6 +35,7 @@
* A network recommendation provider is any application which:
* <ul>
* <li>Is granted the {@link permission#SCORE_NETWORKS} permission.
+ * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission.
* <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent
* which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission.
* </ul>
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 7e0c9ce..060af0d 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -38,7 +38,8 @@
*
* <p>A network scorer is any application which:
* <ul>
- * <li>Declares the {@link permission#SCORE_NETWORKS} permission.
+ * <li>Is granted the {@link permission#SCORE_NETWORKS} permission.
+ * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission.
* <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action
* protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE}
* permission.
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 77ce65b..be9e809 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -672,36 +672,33 @@
entry.tag = left.tag[i];
entry.metered = left.metered[i];
entry.roaming = left.roaming[i];
+ entry.rxBytes = left.rxBytes[i];
+ entry.rxPackets = left.rxPackets[i];
+ entry.txBytes = left.txBytes[i];
+ entry.txPackets = left.txPackets[i];
+ entry.operations = left.operations[i];
// find remote row that matches, and subtract
final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
entry.metered, entry.roaming, i);
- if (j == -1) {
- // newly appearing row, return entire value
- entry.rxBytes = left.rxBytes[i];
- entry.rxPackets = left.rxPackets[i];
- entry.txBytes = left.txBytes[i];
- entry.txPackets = left.txPackets[i];
- entry.operations = left.operations[i];
- } else {
- // existing row, subtract remote value
- entry.rxBytes = left.rxBytes[i] - right.rxBytes[j];
- entry.rxPackets = left.rxPackets[i] - right.rxPackets[j];
- entry.txBytes = left.txBytes[i] - right.txBytes[j];
- entry.txPackets = left.txPackets[i] - right.txPackets[j];
- entry.operations = left.operations[i] - right.operations[j];
+ if (j != -1) {
+ // Found matching row, subtract remote value.
+ entry.rxBytes -= right.rxBytes[j];
+ entry.rxPackets -= right.rxPackets[j];
+ entry.txBytes -= right.txBytes[j];
+ entry.txPackets -= right.txPackets[j];
+ entry.operations -= right.operations[j];
+ }
- if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
- || entry.txPackets < 0 || entry.operations < 0) {
- if (observer != null) {
- observer.foundNonMonotonic(left, i, right, j, cookie);
- }
- entry.rxBytes = Math.max(entry.rxBytes, 0);
- entry.rxPackets = Math.max(entry.rxPackets, 0);
- entry.txBytes = Math.max(entry.txBytes, 0);
- entry.txPackets = Math.max(entry.txPackets, 0);
- entry.operations = Math.max(entry.operations, 0);
+ if (entry.isNegative()) {
+ if (observer != null) {
+ observer.foundNonMonotonic(left, i, right, j, cookie);
}
+ entry.rxBytes = Math.max(entry.rxBytes, 0);
+ entry.rxPackets = Math.max(entry.rxPackets, 0);
+ entry.txBytes = Math.max(entry.txBytes, 0);
+ entry.txPackets = Math.max(entry.txPackets, 0);
+ entry.operations = Math.max(entry.operations, 0);
}
result.addValues(entry);
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index ace3748..1e41eea 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -16,6 +16,10 @@
package android.net.nsd;
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.Preconditions.checkStringNotEmpty;
+
import android.annotation.SdkConstant;
import android.annotation.SystemService;
import android.annotation.SdkConstant.SdkConstantType;
@@ -240,12 +244,12 @@
return name;
}
+ private static int FIRST_LISTENER_KEY = 1;
+
private final INsdManager mService;
private final Context mContext;
- private static final int INVALID_LISTENER_KEY = 0;
- private static final int BUSY_LISTENER_KEY = -1;
- private int mListenerKey = 1;
+ private int mListenerKey = FIRST_LISTENER_KEY;
private final SparseArray mListenerMap = new SparseArray();
private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<>();
private final Object mMapLock = new Object();
@@ -311,7 +315,6 @@
public void onServiceFound(NsdServiceInfo serviceInfo);
public void onServiceLost(NsdServiceInfo serviceInfo);
-
}
/** Interface for callback invocation for service registration */
@@ -342,8 +345,9 @@
@Override
public void handleMessage(Message message) {
- if (DBG) Log.d(TAG, "received " + nameOf(message.what));
- switch (message.what) {
+ final int what = message.what;
+ final int key = message.arg2;
+ switch (what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
return;
@@ -356,19 +360,26 @@
default:
break;
}
- Object listener = getListener(message.arg2);
+ final Object listener;
+ final NsdServiceInfo ns;
+ synchronized (mMapLock) {
+ listener = mListenerMap.get(key);
+ ns = mServiceMap.get(key);
+ }
if (listener == null) {
Log.d(TAG, "Stale key " + message.arg2);
return;
}
- NsdServiceInfo ns = getNsdService(message.arg2);
- switch (message.what) {
+ if (DBG) {
+ Log.d(TAG, "received " + nameOf(what) + " for key " + key + ", service " + ns);
+ }
+ switch (what) {
case DISCOVER_SERVICES_STARTED:
String s = getNsdServiceInfoType((NsdServiceInfo) message.obj);
((DiscoveryListener) listener).onDiscoveryStarted(s);
break;
case DISCOVER_SERVICES_FAILED:
- removeListener(message.arg2);
+ removeListener(key);
((DiscoveryListener) listener).onStartDiscoveryFailed(getNsdServiceInfoType(ns),
message.arg1);
break;
@@ -381,16 +392,16 @@
case STOP_DISCOVERY_FAILED:
// TODO: failure to stop discovery should be internal and retried internally, as
// the effect for the client is indistinguishable from STOP_DISCOVERY_SUCCEEDED
- removeListener(message.arg2);
+ removeListener(key);
((DiscoveryListener) listener).onStopDiscoveryFailed(getNsdServiceInfoType(ns),
message.arg1);
break;
case STOP_DISCOVERY_SUCCEEDED:
- removeListener(message.arg2);
+ removeListener(key);
((DiscoveryListener) listener).onDiscoveryStopped(getNsdServiceInfoType(ns));
break;
case REGISTER_SERVICE_FAILED:
- removeListener(message.arg2);
+ removeListener(key);
((RegistrationListener) listener).onRegistrationFailed(ns, message.arg1);
break;
case REGISTER_SERVICE_SUCCEEDED:
@@ -398,7 +409,7 @@
(NsdServiceInfo) message.obj);
break;
case UNREGISTER_SERVICE_FAILED:
- removeListener(message.arg2);
+ removeListener(key);
((RegistrationListener) listener).onUnregistrationFailed(ns, message.arg1);
break;
case UNREGISTER_SERVICE_SUCCEEDED:
@@ -408,11 +419,11 @@
((RegistrationListener) listener).onServiceUnregistered(ns);
break;
case RESOLVE_SERVICE_FAILED:
- removeListener(message.arg2);
+ removeListener(key);
((ResolveListener) listener).onResolveFailed(ns, message.arg1);
break;
case RESOLVE_SERVICE_SUCCEEDED:
- removeListener(message.arg2);
+ removeListener(key);
((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
break;
default:
@@ -422,40 +433,27 @@
}
}
- // if the listener is already in the map, reject it. Otherwise, add it and
- // return its key.
+ private int nextListenerKey() {
+ // Ensure mListenerKey >= FIRST_LISTENER_KEY;
+ mListenerKey = Math.max(FIRST_LISTENER_KEY, mListenerKey + 1);
+ return mListenerKey;
+ }
+
+ // Assert that the listener is not in the map, then add it and returns its key
private int putListener(Object listener, NsdServiceInfo s) {
- if (listener == null) return INVALID_LISTENER_KEY;
- int key;
+ checkListener(listener);
+ final int key;
synchronized (mMapLock) {
int valueIndex = mListenerMap.indexOfValue(listener);
- if (valueIndex != -1) {
- return BUSY_LISTENER_KEY;
- }
- do {
- key = mListenerKey++;
- } while (key == INVALID_LISTENER_KEY);
+ checkArgument(valueIndex == -1, "listener already in use");
+ key = nextListenerKey();
mListenerMap.put(key, listener);
mServiceMap.put(key, s);
}
return key;
}
- private Object getListener(int key) {
- if (key == INVALID_LISTENER_KEY) return null;
- synchronized (mMapLock) {
- return mListenerMap.get(key);
- }
- }
-
- private NsdServiceInfo getNsdService(int key) {
- synchronized (mMapLock) {
- return mServiceMap.get(key);
- }
- }
-
private void removeListener(int key) {
- if (key == INVALID_LISTENER_KEY) return;
synchronized (mMapLock) {
mListenerMap.remove(key);
mServiceMap.remove(key);
@@ -463,16 +461,15 @@
}
private int getListenerKey(Object listener) {
+ checkListener(listener);
synchronized (mMapLock) {
int valueIndex = mListenerMap.indexOfValue(listener);
- if (valueIndex != -1) {
- return mListenerMap.keyAt(valueIndex);
- }
+ checkArgument(valueIndex != -1, "listener not registered");
+ return mListenerMap.keyAt(valueIndex);
}
- return INVALID_LISTENER_KEY;
}
- private String getNsdServiceInfoType(NsdServiceInfo s) {
+ private static String getNsdServiceInfoType(NsdServiceInfo s) {
if (s == null) return "?";
return s.getServiceType();
}
@@ -482,7 +479,9 @@
*/
private void init() {
final Messenger messenger = getMessenger();
- if (messenger == null) throw new RuntimeException("Failed to initialize");
+ if (messenger == null) {
+ fatal("Failed to obtain service Messenger");
+ }
HandlerThread t = new HandlerThread("NsdManager");
t.start();
mHandler = new ServiceHandler(t.getLooper());
@@ -490,10 +489,15 @@
try {
mConnected.await();
} catch (InterruptedException e) {
- Log.e(TAG, "interrupted wait at init");
+ fatal("Interrupted wait at init");
}
}
+ private static void fatal(String msg) {
+ Log.e(TAG, msg);
+ throw new RuntimeException(msg);
+ }
+
/**
* Register a service to be discovered by other services.
*
@@ -513,23 +517,10 @@
*/
public void registerService(NsdServiceInfo serviceInfo, int protocolType,
RegistrationListener listener) {
- if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
- TextUtils.isEmpty(serviceInfo.getServiceType())) {
- throw new IllegalArgumentException("Service name or type cannot be empty");
- }
- if (serviceInfo.getPort() <= 0) {
- throw new IllegalArgumentException("Invalid port number");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
- if (protocolType != PROTOCOL_DNS_SD) {
- throw new IllegalArgumentException("Unsupported protocol");
- }
+ checkArgument(serviceInfo.getPort() > 0, "Invalid port number");
+ checkServiceInfo(serviceInfo);
+ checkProtocol(protocolType);
int key = putListener(listener, serviceInfo);
- if (key == BUSY_LISTENER_KEY) {
- throw new IllegalArgumentException("listener already in use");
- }
mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, key, serviceInfo);
}
@@ -548,12 +539,6 @@
*/
public void unregisterService(RegistrationListener listener) {
int id = getListenerKey(listener);
- if (id == INVALID_LISTENER_KEY) {
- throw new IllegalArgumentException("listener not registered");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
}
@@ -586,25 +571,13 @@
* Cannot be null. Cannot be in use for an active service discovery.
*/
public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
- if (TextUtils.isEmpty(serviceType)) {
- throw new IllegalArgumentException("Service type cannot be empty");
- }
-
- if (protocolType != PROTOCOL_DNS_SD) {
- throw new IllegalArgumentException("Unsupported protocol");
- }
+ checkStringNotEmpty(serviceType, "Service type cannot be empty");
+ checkProtocol(protocolType);
NsdServiceInfo s = new NsdServiceInfo();
s.setServiceType(serviceType);
int key = putListener(listener, s);
- if (key == BUSY_LISTENER_KEY) {
- throw new IllegalArgumentException("listener already in use");
- }
-
mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, key, s);
}
@@ -626,12 +599,6 @@
*/
public void stopServiceDiscovery(DiscoveryListener listener) {
int id = getListenerKey(listener);
- if (id == INVALID_LISTENER_KEY) {
- throw new IllegalArgumentException("service discovery not active on listener");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
}
@@ -645,19 +612,8 @@
* Cannot be in use for an active service resolution.
*/
public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
- if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
- TextUtils.isEmpty(serviceInfo.getServiceType())) {
- throw new IllegalArgumentException("Service name or type cannot be empty");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
-
+ checkServiceInfo(serviceInfo);
int key = putListener(listener, serviceInfo);
-
- if (key == BUSY_LISTENER_KEY) {
- throw new IllegalArgumentException("listener already in use");
- }
mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, key, serviceInfo);
}
@@ -671,10 +627,10 @@
}
/**
- * Get a reference to NetworkService handler. This is used to establish
+ * Get a reference to NsdService handler. This is used to establish
* an AsyncChannel communication with the service
*
- * @return Messenger pointing to the NetworkService handler
+ * @return Messenger pointing to the NsdService handler
*/
private Messenger getMessenger() {
try {
@@ -683,4 +639,18 @@
throw e.rethrowFromSystemServer();
}
}
+
+ private static void checkListener(Object listener) {
+ checkNotNull(listener, "listener cannot be null");
+ }
+
+ private static void checkProtocol(int protocolType) {
+ checkArgument(protocolType == PROTOCOL_DNS_SD, "Unsupported protocol");
+ }
+
+ private static void checkServiceInfo(NsdServiceInfo serviceInfo) {
+ checkNotNull(serviceInfo, "NsdServiceInfo cannot be null");
+ checkStringNotEmpty(serviceInfo.getServiceName(),"Service name cannot be empty");
+ checkStringNotEmpty(serviceInfo.getServiceType(), "Service type cannot be empty");
+ }
}
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
index 4201935..1d3f9c2 100644
--- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
@@ -44,6 +44,8 @@
public final class NfcFServiceInfo implements Parcelable {
static final String TAG = "NfcFServiceInfo";
+ private static final String DEFAULT_T3T_PMM = "FFFFFFFFFFFFFFFF";
+
/**
* The service that implements this
*/
@@ -173,16 +175,12 @@
com.android.internal.R.styleable.T3tPmmFilter);
t3tPmm = a.getString(
com.android.internal.R.styleable.T3tPmmFilter_name).toUpperCase();
- if (t3tPmm == null) {
- String defaultT3tPmm = "FFFFFFFFFFFFFFFF";
- t3tPmm = defaultT3tPmm;
- }
a.recycle();
}
}
mSystemCode = (systemCode == null ? "NULL" : systemCode);
mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2);
- mT3tPmm = (t3tPmm == null ? "NULL" : t3tPmm);
+ mT3tPmm = (t3tPmm == null ? DEFAULT_T3T_PMM : t3tPmm);
} catch (NameNotFoundException e) {
throw new XmlPullParserException("Unable to create context for: " + si.packageName);
} finally {
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index a5763ef..5312dca 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.Log;
@@ -23,6 +24,7 @@
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import java.io.Serializable;
@@ -94,7 +96,8 @@
private ClassLoader mClassLoader;
/** {@hide} */
- int mFlags;
+ @VisibleForTesting
+ public int mFlags;
/**
* Constructs a new, empty Bundle that uses a specific ClassLoader for
@@ -218,59 +221,72 @@
*/
/* package */ void unparcel() {
synchronized (this) {
- final Parcel parcelledData = mParcelledData;
- if (parcelledData == null) {
- if (DEBUG) Log.d(TAG, "unparcel "
- + Integer.toHexString(System.identityHashCode(this))
- + ": no parcelled data");
- return;
- }
-
- if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
- Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
- + "clobber all data inside!", new Throwable());
- }
-
- if (isEmptyParcel()) {
- if (DEBUG) Log.d(TAG, "unparcel "
- + Integer.toHexString(System.identityHashCode(this)) + ": empty");
- if (mMap == null) {
- mMap = new ArrayMap<>(1);
- } else {
- mMap.erase();
- }
- mParcelledData = null;
- return;
- }
-
- int N = parcelledData.readInt();
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": reading " + N + " maps");
- if (N < 0) {
- return;
- }
- ArrayMap<String, Object> map = mMap;
- if (map == null) {
- map = new ArrayMap<>(N);
+ final Parcel source = mParcelledData;
+ if (source != null) {
+ initializeFromParcelLocked(source, /*recycleParcel=*/ true);
} else {
- map.erase();
- map.ensureCapacity(N);
- }
- try {
- parcelledData.readArrayMapInternal(map, N, mClassLoader);
- } catch (BadParcelableException e) {
- if (sShouldDefuse) {
- Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
- map.erase();
- } else {
- throw e;
+ if (DEBUG) {
+ Log.d(TAG, "unparcel "
+ + Integer.toHexString(System.identityHashCode(this))
+ + ": no parcelled data");
}
- } finally {
- mMap = map;
- parcelledData.recycle();
- mParcelledData = null;
}
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ }
+ }
+
+ private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel) {
+ if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
+ Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
+ + "clobber all data inside!", new Throwable());
+ }
+
+ if (isEmptyParcel(parcelledData)) {
+ if (DEBUG) {
+ Log.d(TAG, "unparcel "
+ + Integer.toHexString(System.identityHashCode(this)) + ": empty");
+ }
+ if (mMap == null) {
+ mMap = new ArrayMap<>(1);
+ } else {
+ mMap.erase();
+ }
+ mParcelledData = null;
+ return;
+ }
+
+ final int count = parcelledData.readInt();
+ if (DEBUG) {
+ Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + ": reading " + count + " maps");
+ }
+ if (count < 0) {
+ return;
+ }
+ ArrayMap<String, Object> map = mMap;
+ if (map == null) {
+ map = new ArrayMap<>(count);
+ } else {
+ map.erase();
+ map.ensureCapacity(count);
+ }
+ try {
+ parcelledData.readArrayMapInternal(map, count, mClassLoader);
+ } catch (BadParcelableException e) {
+ if (sShouldDefuse) {
+ Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
+ map.erase();
+ } else {
+ throw e;
+ }
+ } finally {
+ mMap = map;
+ if (recycleParcel) {
+ recycleParcel(parcelledData);
+ }
+ mParcelledData = null;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ " final map: " + mMap);
}
}
@@ -286,7 +302,20 @@
* @hide
*/
public boolean isEmptyParcel() {
- return mParcelledData == NoImagePreloadHolder.EMPTY_PARCEL;
+ return isEmptyParcel(mParcelledData);
+ }
+
+ /**
+ * @hide
+ */
+ private static boolean isEmptyParcel(Parcel p) {
+ return p == NoImagePreloadHolder.EMPTY_PARCEL;
+ }
+
+ private static void recycleParcel(Parcel p) {
+ if (p != null && !isEmptyParcel(p)) {
+ p.recycle();
+ }
}
/** @hide */
@@ -1476,6 +1505,10 @@
* @param parcel The parcel to copy this bundle to.
*/
void writeToParcelInner(Parcel parcel, int flags) {
+ // If the parcel has a read-write helper, we can't just copy the blob, so unparcel it first.
+ if (parcel.hasReadWriteHelper()) {
+ unparcel();
+ }
// Keep implementation in sync with writeToParcel() in
// frameworks/native/libs/binder/PersistableBundle.cpp.
final ArrayMap<String, Object> map;
@@ -1544,6 +1577,15 @@
+ Integer.toHexString(magic));
}
+ if (parcel.hasReadWriteHelper()) {
+ // If the parcel has a read-write helper, then we can't lazily-unparcel it, so just
+ // unparcel right away.
+ synchronized (this) {
+ initializeFromParcelLocked(parcel, /*recycleParcel=*/ false);
+ }
+ return;
+ }
+
// Advance within this Parcel
int offset = parcel.dataPosition();
parcel.setDataPosition(MathUtils.addOrThrow(offset, length));
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 54d5860..6d44330 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -206,8 +206,15 @@
* - CPU frequency time per uid
* New in version 22:
* - BLE scan result background count, BLE unoptimized scan time
+ * - Background partial wakelock time & count
+ * New in version 23:
+ * - Logging smeared power model values
+ * New in version 24:
+ * - Fixed bugs in background timers and BLE scan time
+ * New in version 25:
+ * - Package wakeup alarms are now on screen-off timebase
*/
- static final String CHECKIN_VERSION = "24";
+ static final String CHECKIN_VERSION = "25";
/**
* Old version, we hit 9 and ran out of room, need to remove.
@@ -686,7 +693,7 @@
public abstract long getSystemCpuTimeUs(int which);
/**
- * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed for a
+ * Returns the approximate cpu time (in microseconds) spent at a certain CPU speed for a
* given CPU cluster.
* @param cluster the index of the CPU cluster.
* @param step the index of the CPU speed. This is not the actual speed of the CPU.
@@ -3544,6 +3551,12 @@
if (name.indexOf(',') >= 0) {
name = name.replace(',', '_');
}
+ if (name.indexOf('\n') >= 0) {
+ name = name.replace('\n', '_');
+ }
+ if (name.indexOf('\r') >= 0) {
+ name = name.replace('\r', '_');
+ }
dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
}
}
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 5331304..0df6361 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -16,6 +16,8 @@
package android.os;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.util.ExceptionUtils;
import android.util.Log;
import android.util.Slog;
@@ -218,7 +220,7 @@
* with their own uid. If the current thread is not currently executing an
* incoming transaction, then its own UserHandle is returned.
*/
- public static final UserHandle getCallingUserHandle() {
+ public static final @NonNull UserHandle getCallingUserHandle() {
return UserHandle.of(UserHandle.getUserId(getCallingUid()));
}
@@ -261,7 +263,7 @@
*
* @hide
*/
- public static final void withCleanCallingIdentity(ThrowingRunnable action) {
+ public static final void withCleanCallingIdentity(@NonNull ThrowingRunnable action) {
long callingIdentity = clearCallingIdentity();
Throwable throwableToPropagate = null;
try {
@@ -285,7 +287,7 @@
*
* @hide
*/
- public static final <T> T withCleanCallingIdentity(ThrowingSupplier<T> action) {
+ public static final <T> T withCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) {
long callingIdentity = clearCallingIdentity();
Throwable throwableToPropagate = null;
try {
@@ -377,7 +379,7 @@
* to return the given owner IInterface when the corresponding
* descriptor is requested.
*/
- public void attachInterface(IInterface owner, String descriptor) {
+ public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
@@ -385,7 +387,7 @@
/**
* Default implementation returns an empty interface name.
*/
- public String getInterfaceDescriptor() {
+ public @Nullable String getInterfaceDescriptor() {
return mDescriptor;
}
@@ -412,7 +414,7 @@
* associated IInterface if it matches the requested
* descriptor.
*/
- public IInterface queryLocalInterface(String descriptor) {
+ public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
@@ -438,8 +440,25 @@
* to override this to do the appropriate unmarshalling of transactions.
*
* <p>If you want to call this, call transact().
+ *
+ * <p>Implementations that are returning a result should generally use
+ * {@link Parcel#writeNoException() Parcel.writeNoException} and
+ * {@link Parcel#writeException(Exception) Parcel.writeException} to propagate
+ * exceptions back to the caller.</p>
+ *
+ * @param code The action to perform. This should
+ * be a number between {@link #FIRST_CALL_TRANSACTION} and
+ * {@link #LAST_CALL_TRANSACTION}.
+ * @param data Marshalled data being received from the caller.
+ * @param reply If the caller is expecting a result back, it should be marshalled
+ * in to here.
+ * @param flags Additional operation flags. Either 0 for a normal
+ * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
+ *
+ * @return Return true on a successful call; returning false is generally used to
+ * indicate that you did not understand the transaction code.
*/
- protected boolean onTransact(int code, Parcel data, Parcel reply,
+ protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
int flags) throws RemoteException {
if (code == INTERFACE_TRANSACTION) {
reply.writeString(getInterfaceDescriptor());
@@ -495,7 +514,7 @@
* Implemented to call the more convenient version
* {@link #dump(FileDescriptor, PrintWriter, String[])}.
*/
- public void dump(FileDescriptor fd, String[] args) {
+ public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new FastPrintWriter(fout);
try {
@@ -531,7 +550,7 @@
* Like {@link #dump(FileDescriptor, String[])}, but ensures the target
* executes asynchronously.
*/
- public void dumpAsync(final FileDescriptor fd, final String[] args) {
+ public void dumpAsync(@NonNull final FileDescriptor fd, @Nullable final String[] args) {
final FileOutputStream fout = new FileOutputStream(fd);
final PrintWriter pw = new FastPrintWriter(fout);
Thread thr = new Thread("Binder.dumpAsync") {
@@ -554,7 +573,8 @@
* closed for you after you return.
* @param args additional arguments to the dump request.
*/
- protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
+ @Nullable String[] args) {
}
/**
@@ -567,9 +587,10 @@
* @throws RemoteException
* @hide
*/
- public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, ShellCallback callback,
- ResultReceiver resultReceiver) throws RemoteException {
+ public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err,
+ @NonNull String[] args, @Nullable ShellCallback callback,
+ @NonNull ResultReceiver resultReceiver) throws RemoteException {
onShellCommand(in, out, err, args, callback, resultReceiver);
}
@@ -581,8 +602,10 @@
* Consider using {@link ShellCommand} to help in the implementation.</p>
* @hide
*/
- public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException {
+ public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err,
+ @NonNull String[] args, @Nullable ShellCallback callback,
+ @NonNull ResultReceiver resultReceiver) throws RemoteException {
FileOutputStream fout = new FileOutputStream(err != null ? err : out);
PrintWriter pw = new FastPrintWriter(fout);
pw.println("No shell command implementation.");
@@ -594,7 +617,7 @@
* Default implementation rewinds the parcels and calls onTransact. On
* the remote side, transact calls into the binder to do the IPC.
*/
- public final boolean transact(int code, Parcel data, Parcel reply,
+ public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
int flags) throws RemoteException {
if (false) Log.v("Binder", "Transact: " + code + " to " + this);
@@ -611,13 +634,13 @@
/**
* Local implementation is a no-op.
*/
- public void linkToDeath(DeathRecipient recipient, int flags) {
+ public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
}
/**
* Local implementation is a no-op.
*/
- public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+ public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
return true;
}
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 51f96ee..c58153a 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -22,6 +22,8 @@
import android.util.SizeF;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -32,9 +34,14 @@
* @see PersistableBundle
*/
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
- private static final int FLAG_HAS_FDS = 1 << 8;
- private static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
- private static final int FLAG_ALLOW_FDS = 1 << 10;
+ @VisibleForTesting
+ static final int FLAG_HAS_FDS = 1 << 8;
+
+ @VisibleForTesting
+ static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
+
+ @VisibleForTesting
+ static final int FLAG_ALLOW_FDS = 1 << 10;
public static final Bundle EMPTY;
@@ -65,20 +72,42 @@
* will be unparcelled on first contact, using the assigned ClassLoader.
*
* @param parcelledData a Parcel containing a Bundle
+ *
+ * @hide
*/
- Bundle(Parcel parcelledData) {
+ @VisibleForTesting
+ public Bundle(Parcel parcelledData) {
super(parcelledData);
- mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
- if (mParcelledData.hasFileDescriptors()) {
- mFlags |= FLAG_HAS_FDS;
- }
+ mFlags = FLAG_ALLOW_FDS;
+ maybePrefillHasFds();
}
- /* package */ Bundle(Parcel parcelledData, int length) {
+ /**
+ * Constructor from a parcel for when the length is known *and is not stored in the parcel.*
+ * The other constructor that takes a parcel assumes the length is in the parcel.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public Bundle(Parcel parcelledData, int length) {
super(parcelledData, length);
- mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
- if (mParcelledData.hasFileDescriptors()) {
- mFlags |= FLAG_HAS_FDS;
+ mFlags = FLAG_ALLOW_FDS;
+ maybePrefillHasFds();
+ }
+
+ /**
+ * If {@link #mParcelledData} is not null, copy the HAS FDS bit from it because it's fast.
+ * Otherwise (if {@link #mParcelledData} is already null), leave {@link #FLAG_HAS_FDS_KNOWN}
+ * unset, because scanning a map is slower. We'll do it lazily in
+ * {@link #hasFileDescriptors()}.
+ */
+ private void maybePrefillHasFds() {
+ if (mParcelledData != null) {
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS | FLAG_HAS_FDS_KNOWN;
+ } else {
+ mFlags |= FLAG_HAS_FDS_KNOWN;
+ }
}
}
@@ -1213,10 +1242,8 @@
*/
public void readFromParcel(Parcel parcel) {
super.readFromParcelInner(parcel);
- mFlags = FLAG_HAS_FDS_KNOWN | FLAG_ALLOW_FDS;
- if (mParcelledData.hasFileDescriptors()) {
- mFlags |= FLAG_HAS_FDS;
- }
+ mFlags = FLAG_ALLOW_FDS;
+ maybePrefillHasFds();
}
@Override
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index f762a05..e74b0bb 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -16,6 +16,9 @@
package android.os;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import java.io.FileDescriptor;
/**
@@ -153,6 +156,14 @@
* caller returns immediately, without waiting for a result from the
* callee. Applies only if the caller and callee are in different
* processes.
+ *
+ * <p>The system provides special ordering semantics for multiple oneway calls
+ * being made to the same IBinder object: these calls will be dispatched in the
+ * other process one at a time, with the same order as the original calls. These
+ * are still dispatched by the IPC thread pool, so may execute on different threads,
+ * but the next one will not be dispatched until the previous one completes. This
+ * ordering is not guaranteed for calls on different IBinder objects or when mixing
+ * oneway and non-oneway calls on the same IBinder object.</p>
*/
int FLAG_ONEWAY = 0x00000001;
@@ -166,7 +177,7 @@
/**
* Get the canonical name of the interface supported by this binder.
*/
- public String getInterfaceDescriptor() throws RemoteException;
+ public @Nullable String getInterfaceDescriptor() throws RemoteException;
/**
* Check to see if the object still exists.
@@ -192,7 +203,7 @@
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
- public IInterface queryLocalInterface(String descriptor);
+ public @Nullable IInterface queryLocalInterface(@NonNull String descriptor);
/**
* Print the object's state into the given stream.
@@ -200,7 +211,7 @@
* @param fd The raw file descriptor that the dump is being sent to.
* @param args additional arguments to the dump request.
*/
- public void dump(FileDescriptor fd, String[] args) throws RemoteException;
+ public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) throws RemoteException;
/**
* Like {@link #dump(FileDescriptor, String[])} but always executes
@@ -210,7 +221,8 @@
* @param fd The raw file descriptor that the dump is being sent to.
* @param args additional arguments to the dump request.
*/
- public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
+ public void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args)
+ throws RemoteException;
/**
* Execute a shell command on this object. This may be performed asynchrously from the caller;
@@ -224,9 +236,10 @@
* @param resultReceiver Called when the command has finished executing, with the result code.
* @hide
*/
- public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, ShellCallback shellCallback,
- ResultReceiver resultReceiver) throws RemoteException;
+ public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err,
+ @NonNull String[] args, @Nullable ShellCallback shellCallback,
+ @NonNull ResultReceiver resultReceiver) throws RemoteException;
/**
* Perform a generic operation with the object.
@@ -241,8 +254,12 @@
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
+ *
+ * @return Returns the result from {@link Binder#onTransact}. A successful call
+ * generally returns true; false generally means the transaction code was not
+ * understood.
*/
- public boolean transact(int code, Parcel data, Parcel reply, int flags)
+ public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
throws RemoteException;
/**
@@ -271,7 +288,7 @@
*
* @see #unlinkToDeath
*/
- public void linkToDeath(DeathRecipient recipient, int flags)
+ public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
throws RemoteException;
/**
@@ -292,5 +309,5 @@
* exception will <em>not</em> be thrown, and you will receive a false
* return value instead.
*/
- public boolean unlinkToDeath(DeathRecipient recipient, int flags);
+ public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
}
diff --git a/core/java/android/os/IThermalEventListener.aidl b/core/java/android/os/IThermalEventListener.aidl
new file mode 100644
index 0000000..9a6de60
--- /dev/null
+++ b/core/java/android/os/IThermalEventListener.aidl
@@ -0,0 +1,32 @@
+/*
+** 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.os;
+
+import android.os.Temperature;
+
+/**
+ * Listener for thermal events.
+ * {@hide}
+ */
+oneway interface IThermalEventListener {
+ /**
+ * Called when a thermal throttling start/stop event is received.
+ * @param temperature the temperature at which the event was generated.
+ */
+ void notifyThrottling(
+ in boolean isThrottling, in Temperature temperature);
+}
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
new file mode 100644
index 0000000..e388eda
--- /dev/null
+++ b/core/java/android/os/IThermalService.aidl
@@ -0,0 +1,51 @@
+/*
+** 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.os;
+
+import android.os.IThermalEventListener;
+import android.os.Temperature;
+
+/**
+ * {@hide}
+ */
+interface IThermalService {
+ /**
+ * Register a listener for thermal events.
+ * @param listener the IThermalEventListener to be notified.
+ * {@hide}
+ */
+ void registerThermalEventListener(in IThermalEventListener listener);
+ /**
+ * Unregister a previously-registered listener for thermal events.
+ * @param listener the IThermalEventListener to no longer be notified.
+ * {@hide}
+ */
+ void unregisterThermalEventListener(in IThermalEventListener listener);
+ /**
+ * Send a thermal throttling start/stop notification to all listeners.
+ * @param temperature the temperature at which the event was generated.
+ * {@hide}
+ */
+ oneway void notifyThrottling(
+ in boolean isThrottling, in Temperature temperature);
+ /**
+ * Return whether system performance is currently thermal throttling.
+ * @return true if thermal throttling is currently in effect
+ * {@hide}
+ */
+ boolean isThrottling();
+}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 10331b9..fae9d53 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -291,7 +291,7 @@
private static native void nativeWriteFloat(long nativePtr, float val);
@FastNative
private static native void nativeWriteDouble(long nativePtr, double val);
- private static native void nativeWriteString(long nativePtr, String val);
+ static native void nativeWriteString(long nativePtr, String val);
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
@@ -306,7 +306,7 @@
private static native float nativeReadFloat(long nativePtr);
@CriticalNative
private static native double nativeReadDouble(long nativePtr);
- private static native String nativeReadString(long nativePtr);
+ static native String nativeReadString(long nativePtr);
private static native IBinder nativeReadStrongBinder(long nativePtr);
private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
@@ -339,6 +339,33 @@
};
/**
+ * @hide
+ */
+ public static class ReadWriteHelper {
+ public static final ReadWriteHelper DEFAULT = new ReadWriteHelper();
+
+ /**
+ * Called when writing a string to a parcel. Subclasses wanting to write a string
+ * must use {@link #writeStringNoHelper(String)} to avoid
+ * infinity recursive calls.
+ */
+ public void writeString(Parcel p, String s) {
+ nativeWriteString(p.mNativePtr, s);
+ }
+
+ /**
+ * Called when reading a string to a parcel. Subclasses wanting to read a string
+ * must use {@link #readStringNoHelper()} to avoid
+ * infinity recursive calls.
+ */
+ public String readString(Parcel p) {
+ return nativeReadString(p.mNativePtr);
+ }
+ }
+
+ private ReadWriteHelper mReadWriteHelper = ReadWriteHelper.DEFAULT;
+
+ /**
* Retrieve a new Parcel object from the pool.
*/
public static Parcel obtain() {
@@ -352,6 +379,7 @@
if (DEBUG_RECYCLE) {
p.mStack = new RuntimeException();
}
+ p.mReadWriteHelper = ReadWriteHelper.DEFAULT;
return p;
}
}
@@ -385,6 +413,25 @@
}
}
+ /**
+ * Set a {@link ReadWriteHelper}, which can be used to avoid having duplicate strings, for
+ * example.
+ *
+ * @hide
+ */
+ public void setReadWriteHelper(ReadWriteHelper helper) {
+ mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT;
+ }
+
+ /**
+ * @return whether this parcel has a {@link ReadWriteHelper}.
+ *
+ * @hide
+ */
+ public boolean hasReadWriteHelper() {
+ return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT);
+ }
+
/** @hide */
public static native long getGlobalAllocSize();
@@ -625,6 +672,17 @@
* growing dataCapacity() if needed.
*/
public final void writeString(String val) {
+ mReadWriteHelper.writeString(this, val);
+ }
+
+ /**
+ * Write a string without going though a {@link ReadWriteHelper}. Subclasses of
+ * {@link ReadWriteHelper} must use this method instead of {@link #writeString} to avoid
+ * infinity recursive calls.
+ *
+ * @hide
+ */
+ public void writeStringNoHelper(String val) {
nativeWriteString(mNativePtr, val);
}
@@ -1782,6 +1840,7 @@
* <li>{@link IllegalStateException}
* <li>{@link NullPointerException}
* <li>{@link SecurityException}
+ * <li>{@link UnsupportedOperationException}
* <li>{@link NetworkOnMainThreadException}
* </ul>
*
@@ -1996,6 +2055,17 @@
* Read a string value from the parcel at the current dataPosition().
*/
public final String readString() {
+ return mReadWriteHelper.readString(this);
+ }
+
+ /**
+ * Read a string without going though a {@link ReadWriteHelper}. Subclasses of
+ * {@link ReadWriteHelper} must use this method instead of {@link #readString} to avoid
+ * infinity recursive calls.
+ *
+ * @hide
+ */
+ public String readStringNoHelper() {
return nativeReadString(mNativePtr);
}
@@ -2996,6 +3066,7 @@
if (mOwnsNativeParcelObject) {
updateNativeSize(nativeFreeBuffer(mNativePtr));
}
+ mReadWriteHelper = ReadWriteHelper.DEFAULT;
}
private void destroy() {
@@ -3006,6 +3077,7 @@
}
mNativePtr = 0;
}
+ mReadWriteHelper = null;
}
@Override
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 712bbaa..459aeb0 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -28,6 +28,7 @@
import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.DirectByteBuffer;
+import java.nio.NioUtils;
import sun.misc.Cleaner;
@@ -191,11 +192,16 @@
}
/**
- * Creates an mmap of the SharedMemory with the specified prot, offset, and length.
+ * Creates an mmap of the SharedMemory with the specified prot, offset, and length. This will
+ * always produce a new ByteBuffer window to the backing shared memory region. Every call
+ * to map() may be paired with a call to {@link #unmap(ByteBuffer)} when the ByteBuffer
+ * returned by map() is no longer needed.
*
* @param prot A bitwise-or'd combination of PROT_READ, PROT_WRITE, PROT_EXEC, or PROT_NONE.
- * @param offset The offset into the shared memory to begin mapping
- * @param length The length of the region to map
+ * @param offset The offset into the shared memory to begin mapping. Must be >= 0 and less than
+ * getSize().
+ * @param length The length of the region to map. Must be > 0 and offset + length must not
+ * exceed getSize().
* @return A ByteBuffer mapping.
* @throws ErrnoException if the mmap call failed.
*/
@@ -203,7 +209,7 @@
checkOpen();
validateProt(prot);
if (offset < 0) {
- throw new IllegalArgumentException("Offset must be > 0");
+ throw new IllegalArgumentException("Offset must be >= 0");
}
if (length <= 0) {
throw new IllegalArgumentException("Length must be > 0");
@@ -218,15 +224,16 @@
}
/**
- * Unmaps a buffer previously returned by {@link #map(int, int, int)}
+ * Unmaps a buffer previously returned by {@link #map(int, int, int)}. This will immediately
+ * release the backing memory of the ByteBuffer, invalidating all references to it. Only
+ * call this method if there are no duplicates of the ByteBuffer in use and don't
+ * access the ByteBuffer after calling this method.
+ *
* @param buffer The buffer to unmap
*/
public static void unmap(@NonNull ByteBuffer buffer) {
if (buffer instanceof DirectByteBuffer) {
- Cleaner cleaner = ((DirectByteBuffer) buffer).cleaner();
- if (cleaner != null) {
- cleaner.clean();
- }
+ NioUtils.freeDirectBuffer(buffer);
} else {
throw new IllegalArgumentException(
"ByteBuffer wasn't created by #map(int, int, int); can't unmap");
diff --git a/core/java/android/os/Temperature.aidl b/core/java/android/os/Temperature.aidl
new file mode 100644
index 0000000..708c08f
--- /dev/null
+++ b/core/java/android/os/Temperature.aidl
@@ -0,0 +1,19 @@
+/*
+** 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.os;
+
+parcelable Temperature;
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
new file mode 100644
index 0000000..3e48493
--- /dev/null
+++ b/core/java/android/os/Temperature.java
@@ -0,0 +1,101 @@
+/*
+ * 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.os;
+
+/**
+ * Temperature values used by IThermalService.
+ */
+
+/**
+ * @hide
+ */
+public class Temperature implements Parcelable {
+ /* Temperature value */
+ private float mValue;
+ /* A temperature type from HardwarePropertiesManager */
+ private int mType;
+
+ public Temperature() {
+ mType = Integer.MIN_VALUE;
+ mValue = HardwarePropertiesManager.UNDEFINED_TEMPERATURE;
+ }
+
+ public Temperature(float value, int type) {
+ mValue = value;
+ mType = type;
+ }
+
+ /**
+ * Return the temperature value.
+ * @return a temperature value in floating point.
+ */
+ public float getValue() {
+ return mValue;
+ }
+
+ /**
+ * Return the temperature type.
+ * @return a temperature type:
+ * HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU, etc.
+ */
+ public int getType() {
+ return mType;
+ }
+
+ /*
+ * Parcel read/write code must be kept in sync with
+ * frameworks/native/services/thermalservice/aidl/android/os/
+ * Temperature.cpp
+ */
+
+ private Temperature(Parcel p) {
+ readFromParcel(p);
+ }
+
+ /**
+ * Fill in Temperature members from a Parcel.
+ * @param p the parceled Temperature object.
+ */
+ public void readFromParcel(Parcel p) {
+ mValue = p.readFloat();
+ mType = p.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel p, int flags) {
+ p.writeFloat(mValue);
+ p.writeInt(mType);
+ }
+
+ public static final Parcelable.Creator<Temperature> CREATOR =
+ new Parcelable.Creator<Temperature>() {
+ @Override
+ public Temperature createFromParcel(Parcel p) {
+ return new Temperature(p);
+ }
+
+ @Override
+ public Temperature[] newArray(int size) {
+ return new Temperature[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 6a4fef2..e8ebf63 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -158,6 +158,11 @@
}
/** @hide */
+ public static @AppIdInt int getCallingAppId() {
+ return getAppId(Binder.getCallingUid());
+ }
+
+ /** @hide */
@SystemApi
public static UserHandle of(@UserIdInt int userId) {
return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 12013fc..6ec755b 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -303,10 +303,12 @@
public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
/**
- * Specifies if a user is disallowed from configuring VPN.
- * The default value is <code>false</code>.
- * This restriction has an effect in a managed profile only from
- * {@link android.os.Build.VERSION_CODES#M}
+ * Specifies if a user is disallowed from configuring a VPN. The default value is
+ * <code>false</code>. This restriction has an effect when set by device owners and, in Android
+ * 6.0 ({@linkplain android.os.Build.VERSION_CODES#M API level 23}) or higher, profile owners.
+ * <p>This restriction also prevents VPNs from starting. However, in Android 7.0
+ * ({@linkplain android.os.Build.VERSION_CODES#N API level 24}) or higher, the system does
+ * start always-on VPNs created by the device or profile owner.
*
* <p>Key for user restrictions.
* <p>Type: Boolean
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 6372113..8533c7e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1662,8 +1662,8 @@
* itself on the given storage volume. This value is typically larger than
* {@link File#getUsableSpace()}, since the system may be willing to delete
* cached files to satisfy an allocation request. You can then allocate
- * space for yourself using {@link #allocateBytes(UUID, long, int)} or
- * {@link #allocateBytes(FileDescriptor, long, int)}.
+ * space for yourself using {@link #allocateBytes(UUID, long)} or
+ * {@link #allocateBytes(FileDescriptor, long)}.
* <p>
* This method is best used as a pre-flight check, such as deciding if there
* is enough space to store an entire music album before you allocate space
@@ -1690,8 +1690,8 @@
* UUID for a specific path can be obtained using
* {@link #getUuidForPath(File)}.
* @return the maximum number of new bytes that the calling app can allocate
- * using {@link #allocateBytes(UUID, long, int)} or
- * {@link #allocateBytes(FileDescriptor, long, int)}.
+ * using {@link #allocateBytes(UUID, long)} or
+ * {@link #allocateBytes(FileDescriptor, long)}.
* @throws IOException when the storage device isn't present, or when it
* doesn't support allocating space.
*/
@@ -1724,11 +1724,11 @@
* files necessary to satisfy your request.
* <p>
* Attempts to allocate disk space beyond the value returned by
- * {@link #getAllocatableBytes(UUID, int)} will fail.
+ * {@link #getAllocatableBytes(UUID)} will fail.
* <p>
* Since multiple apps can be running simultaneously, this method may be
* subject to race conditions. If possible, consider using
- * {@link #allocateBytes(FileDescriptor, long, int)} which will guarantee
+ * {@link #allocateBytes(FileDescriptor, long)} which will guarantee
* that bytes are allocated to an opened file.
* <p>
* If you're progressively allocating an unbounded amount of storage space
@@ -1742,7 +1742,7 @@
* @throws IOException when the storage device isn't present, or when it
* doesn't support allocating space, or if the device had
* trouble allocating the requested space.
- * @see #getAllocatableBytes(UUID, int)
+ * @see #getAllocatableBytes(UUID)
*/
@WorkerThread
public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes)
@@ -1772,7 +1772,7 @@
* necessary to satisfy your request.
* <p>
* Attempts to allocate disk space beyond the value returned by
- * {@link #getAllocatableBytes(UUID, int)} will fail.
+ * {@link #getAllocatableBytes(UUID)} will fail.
* <p>
* This method guarantees that bytes have been allocated to the opened file,
* otherwise it will throw if fast allocation is not possible. Fast
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index f2e2598..ad4ec72 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -44,6 +44,7 @@
import android.os.OperationCanceledException;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.Parcelable;
import android.os.ParcelableException;
import android.os.RemoteException;
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index f909114..d8540ff 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -447,14 +447,14 @@
public FontRequestCallback() {}
/**
- * Called then a Typeface request done via {@link #requestFont} is complete. Note that this
+ * Called then a Typeface request done via {@link #requestFonts} is complete. Note that this
* method will not be called if {@link #onTypefaceRequestFailed(int)} is called instead.
* @param typeface The Typeface object retrieved.
*/
public void onTypefaceRetrieved(Typeface typeface) {}
/**
- * Called when a Typeface request done via {@link #requestFont}} fails.
+ * Called when a Typeface request done via {@link #requestFonts}} fails.
* @param reason One of {@link #FAIL_REASON_PROVIDER_NOT_FOUND},
* {@link #FAIL_REASON_FONT_NOT_FOUND},
* {@link #FAIL_REASON_FONT_LOAD_ERROR},
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 53c82e6..dc9a26e 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -576,21 +576,6 @@
"android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
/**
- * Activity Action: Show a dialog to select input method.
- * <p>
- * In some cases, a matching Activity may not exist, so ensure you
- * safeguard against this.
- * <p>
- * Input: Nothing.
- * <p>
- * Output: Nothing.
- * @hide
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SHOW_INPUT_METHOD_PICKER =
- "android.settings.SHOW_INPUT_METHOD_PICKER";
-
- /**
* Activity Action: Show settings to manage the user input dictionary.
* <p>
* Starting with {@link android.os.Build.VERSION_CODES#KITKAT},
diff --git a/core/java/android/provider/TimeZoneRulesDataContract.java b/core/java/android/provider/TimeZoneRulesDataContract.java
index 33d2588..7a5ae1d 100644
--- a/core/java/android/provider/TimeZoneRulesDataContract.java
+++ b/core/java/android/provider/TimeZoneRulesDataContract.java
@@ -41,6 +41,12 @@
private static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
/**
+ * The permission that the reader of the ContentProvider must possess.
+ */
+ public static final String READER_PERMISSION =
+ android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
+
+ /**
* Defines fields exposed through the {@link Operation#CONTENT_URI} for describing a time zone
* distro operation.
*/
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index a80ef03..c068e6a 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -179,11 +179,18 @@
* should not contain fields for username, password, and credit card information. The reason for
* this rule is that a malicious app could draft a view structure where the credit card fields
* are not visible, so when the user selects a dataset from the username UI, the credit card info is
- * released to the application without the user knowledge. Similar, it's recommended to always
+ * released to the application without the user knowledge. Similarly, it's recommended to always
* protect a dataset that contains sensitive information by requiring dataset authentication
- * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}).
+ * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include
+ * info about the "primary" field of the partition in the custom presentation for "secondary"
+ * fields — that would prevent a malicious app from getting the "primary" fields without the
+ * user realizing they're being released (for example, a malicious app could have fields for a
+ * credit card number, verification code, and expiration date crafted in a way that just the latter
+ * is visible; by explicitly indicating the expiration date is related to a given credit card
+ * number, the service would be providing a visual clue for the users to check what would be
+ * released upon selecting that field).
*
- * <p>When the service detects that a screen have multiple partitions, it should return a
+ * <p>When the service detects that a screen has multiple partitions, it should return a
* {@link FillResponse} with just the datasets for the partition that originated the request (i.e.,
* the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose
* {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if
@@ -236,6 +243,36 @@
* <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous;
* that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions.
*
+ * <h3>Package verification</h3>
+ *
+ * <p>When autofilling app-specific data (like username and password), the service must verify
+ * the authenticity of the request by obtaining all signing certificates of the app being
+ * autofilled, and only fulfilling the request when they match the values that were
+ * obtained when the data was first saved — such verification is necessary to avoid phishing
+ * attempts by apps that were sideloaded in the device with the same package name of another app.
+ * Here's an example on how to achieve that by hashing the signing certificates:
+ *
+ * <pre class="prettyprint">
+ * private String getCertificatesHash(String packageName) throws Exception {
+ * PackageManager pm = mContext.getPackageManager();
+ * PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ * ArrayList<String> hashes = new ArrayList<>(info.signatures.length);
+ * for (Signature sig : info.signatures) {
+ * byte[] cert = sig.toByteArray();
+ * MessageDigest md = MessageDigest.getInstance("SHA-256");
+ * md.update(cert);
+ * hashes.add(toHexString(md.digest()));
+ * }
+ * Collections.sort(hashes);
+ * StringBuilder hash = new StringBuilder();
+ * for (int i = 0; i < hashes.size(); i++) {
+ * hash.append(hashes.get(i));
+ * }
+ * return hash.toString();
+ * }
+ *
+ * </pre>
+ *
* <h3>Ignoring views</h3>
*
* <p>If the service find views that cannot be autofilled (for example, a text field representing
diff --git a/core/java/android/service/autofill/CustomDescription.java b/core/java/android/service/autofill/CustomDescription.java
index 0edb154..3da0b5e 100644
--- a/core/java/android/service/autofill/CustomDescription.java
+++ b/core/java/android/service/autofill/CustomDescription.java
@@ -32,7 +32,7 @@
*
* <p>This is useful when the autofill service needs to show a detailed view of what would be saved;
* for example, when the screen contains a credit card, it could display a logo of the credit card
- * bank, the last for digits of the credit card number, and its expiration number.
+ * bank, the last four digits of the credit card number, and its expiration number.
*
* <p>A custom description is made of 2 parts:
* <ul>
@@ -63,16 +63,16 @@
* // Image child - different logo for each bank, based on credit card prefix
* builder.addChild(R.id.templateccLogo,
* new ImageTransformation.Builder(ccNumberId)
- * .addOption("^4815.*$", R.drawable.ic_credit_card_logo1)
- * .addOption("^1623.*$", R.drawable.ic_credit_card_logo2)
- * .addOption("^42.*$", R.drawable.ic_credit_card_logo3);
+ * .addOption(Pattern.compile(""^4815.*$"), R.drawable.ic_credit_card_logo1)
+ * .addOption(Pattern.compile(""^1623.*$"), R.drawable.ic_credit_card_logo2)
+ * .addOption(Pattern.compile(""^42.*$"), R.drawable.ic_credit_card_logo3);
* // Masked credit card number (as .....LAST_4_DIGITS)
* builder.addChild(R.id.templateCcNumber, new CharSequenceTransformation.Builder()
- * .addField(ccNumberId, "^.*(\\d\\d\\d\\d)$", "...$1")
+ * .addField(ccNumberId, Pattern.compile(""^.*(\\d\\d\\d\\d)$"), "...$1")
* // Expiration date as MM / YYYY:
* builder.addChild(R.id.templateExpDate, new CharSequenceTransformation.Builder()
- * .addField(ccExpMonthId, "^(\\d\\d)$", "Exp: $1")
- * .addField(ccExpYearId, "^(\\d\\d)$", "/$1");
+ * .addField(ccExpMonthId, Pattern.compile(""^(\\d\\d)$"), "Exp: $1")
+ * .addField(ccExpYearId, Pattern.compile(""^(\\d\\d)$"), "/$1");
* </pre>
*
* <p>See {@link ImageTransformation}, {@link CharSequenceTransformation} for more info about these
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index a2ec099..65b0efc 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -26,6 +26,7 @@
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.widget.RemoteViews;
+
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index fd6da05a..1c32fe0 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -61,9 +61,8 @@
* <p>An explicit autofill request is triggered when the
* {@link android.view.autofill.AutofillManager#requestAutofill(View)} or
* {@link android.view.autofill.AutofillManager#requestAutofill(View, int, android.graphics.Rect)}
- * is called. For example, standard {@link android.widget.TextView} views that use
- * an {@link android.widget.Editor} shows an {@code AUTOFILL} option in the overflow menu that
- * triggers such request.
+ * is called. For example, standard {@link android.widget.TextView} views show an
+ * {@code AUTOFILL} option in the overflow menu that triggers such request.
*/
public static final int FLAG_MANUAL_REQUEST = 0x1;
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index e13fdf6..b6a9a26 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -23,15 +23,16 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.content.IntentSender;
+import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
import android.widget.RemoteViews;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Response for a {@link
@@ -41,7 +42,7 @@
*/
public final class FillResponse implements Parcelable {
- private final @Nullable ArrayList<Dataset> mDatasets;
+ private final @Nullable ParceledListSlice<Dataset> mDatasets;
private final @Nullable SaveInfo mSaveInfo;
private final @Nullable Bundle mClientState;
private final @Nullable RemoteViews mPresentation;
@@ -51,7 +52,7 @@
private int mRequestId;
private FillResponse(@NonNull Builder builder) {
- mDatasets = builder.mDatasets;
+ mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
mSaveInfo = builder.mSaveInfo;
mClientState = builder.mCLientState;
mPresentation = builder.mPresentation;
@@ -67,8 +68,8 @@
}
/** @hide */
- public @Nullable ArrayList<Dataset> getDatasets() {
- return mDatasets;
+ public @Nullable List<Dataset> getDatasets() {
+ return (mDatasets != null) ? mDatasets.getList() : null;
}
/** @hide */
@@ -143,12 +144,13 @@
* for the user to trigger your authentication flow.
*
* <p>When a user triggers autofill, the system launches the provided intent
- * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
+ * whose extras will have the
+ * {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
* content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
* client state}. Once you complete your authentication flow you should set the
* {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
- * populated {@link FillResponse response} by setting it to the {@link
- * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
+ * populated {@link FillResponse response} by setting it to the
+ * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
* For example, if you provided an empty {@link FillResponse resppnse} because the
* user's data was locked and marked that the response needs an authentication then
* in the response returned if authentication succeeds you need to provide all
@@ -168,7 +170,7 @@
* @param ids id of Views that when focused will display the authentication UI affordance.
*
* @return This builder.
- * @throw {@link IllegalArgumentException} if {@code ids} is {@code null} or empty, or if
+ * @throws IllegalArgumentException if {@code ids} is {@code null} or empty, or if
* neither {@code authentication} nor {@code presentation} is non-{@code null}.
*
* @see android.app.PendingIntent#getIntentSender()
@@ -205,6 +207,15 @@
/**
* Adds a new {@link Dataset} to this response.
*
+ * <p><b>Note: </b> on Android {@link android.os.Build.VERSION_CODES#O}, the total number of
+ * datasets is limited by the Binder transaction size, so it's recommended to keep it
+ * small (in the range of 10-20 at most) and use pagination by adding a fake
+ * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated dataset} at the end
+ * with a presentation string like "Next 10" that would return a new {@link FillResponse}
+ * with the next 10 datasets, and so on. This limitation was lifted on
+ * Android {@link android.os.Build.VERSION_CODES#O_MR1}, although the Binder transaction
+ * size can still be reached if each dataset itself is too big.
+ *
* @return This builder.
*/
public @NonNull Builder addDataset(@Nullable Dataset dataset) {
@@ -313,7 +324,7 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeTypedArrayList(mDatasets, flags);
+ parcel.writeParcelable(mDatasets, flags);
parcel.writeParcelable(mSaveInfo, flags);
parcel.writeParcelable(mClientState, flags);
parcel.writeParcelableArray(mAuthenticationIds, flags);
@@ -331,7 +342,8 @@
// the system obeys the contract of the builder to avoid attacks
// using specially crafted parcels.
final Builder builder = new Builder();
- final ArrayList<Dataset> datasets = parcel.readTypedArrayList(null);
+ final ParceledListSlice<Dataset> datasetSlice = parcel.readParcelable(null);
+ final List<Dataset> datasets = (datasetSlice != null) ? datasetSlice.getList() : null;
final int datasetCount = (datasets != null) ? datasets.size() : 0;
for (int i = 0; i < datasetCount; i++) {
builder.addDataset(datasets.get(i));
diff --git a/core/java/android/service/autofill/SimpleRegexValidator.java b/core/java/android/service/autofill/RegexValidator.java
similarity index 79%
rename from core/java/android/service/autofill/SimpleRegexValidator.java
rename to core/java/android/service/autofill/RegexValidator.java
index ef8c52c9..9dfe78d 100644
--- a/core/java/android/service/autofill/SimpleRegexValidator.java
+++ b/core/java/android/service/autofill/RegexValidator.java
@@ -34,9 +34,9 @@
*
* <p>See {@link SaveInfo.Builder#setValidator(Validator)} for examples.
*/
-public final class SimpleRegexValidator extends InternalValidator implements Validator, Parcelable {
+public final class RegexValidator extends InternalValidator implements Validator, Parcelable {
- private static final String TAG = "SimpleRegexValidator";
+ private static final String TAG = "RegexValidator";
private final AutofillId mId;
private final Pattern mRegex;
@@ -49,7 +49,7 @@
* matches the contents of the field identified by {@code id}, it returns {@code true};
* otherwise, it returns {@code false}.
*/
- public SimpleRegexValidator(@NonNull AutofillId id, @NonNull Pattern regex) {
+ public RegexValidator(@NonNull AutofillId id, @NonNull Pattern regex) {
mId = Preconditions.checkNotNull(id);
mRegex = Preconditions.checkNotNull(regex);
}
@@ -76,7 +76,7 @@
public String toString() {
if (!sDebug) return super.toString();
- return "SimpleRegexValidator: [id=" + mId + ", regex=" + mRegex + "]";
+ return "RegexValidator: [id=" + mId + ", regex=" + mRegex + "]";
}
/////////////////////////////////////
@@ -93,17 +93,17 @@
parcel.writeSerializable(mRegex);
}
- public static final Parcelable.Creator<SimpleRegexValidator> CREATOR =
- new Parcelable.Creator<SimpleRegexValidator>() {
+ public static final Parcelable.Creator<RegexValidator> CREATOR =
+ new Parcelable.Creator<RegexValidator>() {
@Override
- public SimpleRegexValidator createFromParcel(Parcel parcel) {
- return new SimpleRegexValidator(parcel.readParcelable(null),
+ public RegexValidator createFromParcel(Parcel parcel) {
+ return new RegexValidator(parcel.readParcelable(null),
(Pattern) parcel.readSerializable());
}
@Override
- public SimpleRegexValidator[] newArray(int size) {
- return new SimpleRegexValidator[size];
+ public RegexValidator[] newArray(int size) {
+ return new RegexValidator[size];
}
};
}
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 389341b..e0a0730 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -118,6 +118,9 @@
* <li>The {@link AutofillValue} of at least one view (be it required or optional) has changed
* (i.e., it's neither the same value passed in a {@link Dataset}, nor the initial value
* presented in the view).
+ * <li>There is no {@link Dataset} in the last {@link FillResponse} that completely matches the
+ * screen state (i.e., all required and optional fields in the dataset have the same value as
+ * the fields in the screen).
* <li>The user explicitly tapped the UI affordance asking to save data for autofill.
* </ul>
*
@@ -467,7 +470,7 @@
* <p>Validator for a credit number that must have exactly 16 digits:
*
* <pre class="prettyprint">
- * Validator validator = new SimpleRegexValidator(ccNumberId, "^\\d{16}$")
+ * Validator validator = new RegexValidator(ccNumberId, Pattern.compile(""^\\d{16}$"))
* </pre>
*
* <p>Validator for a credit number that must pass a Luhn checksum and either have
@@ -480,8 +483,8 @@
* and(
* new LuhnChecksumValidator(ccNumberId),
* or(
- * new SimpleRegexValidator(ccNumberId, "^\\d{16}$"),
- * new SimpleRegexValidator(ccNumberId, "^108\\d{12}$")
+ * new RegexValidator(ccNumberId, Pattern.compile(""^\\d{16}$")),
+ * new RegexValidator(ccNumberId, Pattern.compile(""^108\\d{12}$"))
* )
* );
* </pre>
@@ -493,7 +496,7 @@
* Validator validator =
* and(
* new LuhnChecksumValidator(ccNumberId),
- * new SimpleRegexValidator(ccNumberId, "^(\\d{16}|108\\d{12})$")
+ * new RegexValidator(ccNumberId, Pattern.compile(""^(\\d{16}|108\\d{12})$"))
* );
* </pre>
*
@@ -505,10 +508,10 @@
*
* Validator validator =
* and(
- * new SimpleRegexValidator(ccNumberId1, "^\\d{4}$"),
- * new SimpleRegexValidator(ccNumberId2, "^\\d{4}$"),
- * new SimpleRegexValidator(ccNumberId3, "^\\d{4}$"),
- * new SimpleRegexValidator(ccNumberId4, "^\\d{4}$")
+ * new RegexValidator(ccNumberId1, Pattern.compile(""^\\d{4}$")),
+ * new RegexValidator(ccNumberId2, Pattern.compile(""^\\d{4}$")),
+ * new RegexValidator(ccNumberId3, Pattern.compile(""^\\d{4}$")),
+ * new RegexValidator(ccNumberId4, Pattern.compile(""^\\d{4}$"))
* );
* </pre>
*
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 855c87b..a5223fd 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -27,6 +27,7 @@
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.Service;
+import android.companion.CompanionDeviceManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -64,7 +65,7 @@
* A service that receives calls from the system when new notifications are
* posted or removed, or their ranking changed.
* <p>To extend this class, you must declare the service in your manifest file with
- * the {@link Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
+ * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
* and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
* <pre>
* <service android:name=".NotificationListener"
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 6ba11b9..7bec898 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -712,7 +712,8 @@
int userHandle, boolean shortVersion) {
final int num;
String summary, line1, line2;
- final CharSequence formattedTime = getFormattedTime(context, time, userHandle);
+ final CharSequence formattedTime =
+ getFormattedTime(context, time, isToday(time), userHandle);
final Resources res = context.getResources();
if (minutes < 60) {
// display as minutes
@@ -738,33 +739,43 @@
// display as day/time
summary = line1 = line2 = res.getString(R.string.zen_mode_until, formattedTime);
}
- final Uri id = toCountdownConditionId(time);
+ final Uri id = toCountdownConditionId(time, false);
return new Condition(id, summary, line1, line2, 0, Condition.STATE_TRUE,
Condition.FLAG_RELEVANT_NOW);
}
- public static Condition toNextAlarmCondition(Context context, long now, long alarm,
+ /**
+ * Converts countdown to alarm parameters into a condition with user facing summary
+ */
+ public static Condition toNextAlarmCondition(Context context, long alarm,
int userHandle) {
- final CharSequence formattedTime = getFormattedTime(context, alarm, userHandle);
+ boolean isSameDay = isToday(alarm);
+ final CharSequence formattedTime = getFormattedTime(context, alarm, isSameDay, userHandle);
final Resources res = context.getResources();
- final String line1 = res.getString(R.string.zen_mode_alarm, formattedTime);
- final Uri id = toCountdownConditionId(alarm);
+ final String line1 = res.getString(R.string.zen_mode_until, formattedTime);
+ final Uri id = toCountdownConditionId(alarm, true);
return new Condition(id, "", line1, "", 0, Condition.STATE_TRUE,
Condition.FLAG_RELEVANT_NOW);
}
- private static CharSequence getFormattedTime(Context context, long time, int userHandle) {
- String skeleton = "EEE " + (DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma");
+ private static CharSequence getFormattedTime(Context context, long time, boolean isSameDay,
+ int userHandle) {
+ String skeleton = (!isSameDay ? "EEE " : "")
+ + (DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma");
+ final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+ return DateFormat.format(pattern, time);
+ }
+
+ private static boolean isToday(long time) {
GregorianCalendar now = new GregorianCalendar();
GregorianCalendar endTime = new GregorianCalendar();
endTime.setTimeInMillis(time);
if (now.get(Calendar.YEAR) == endTime.get(Calendar.YEAR)
&& now.get(Calendar.MONTH) == endTime.get(Calendar.MONTH)
&& now.get(Calendar.DATE) == endTime.get(Calendar.DATE)) {
- skeleton = DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma";
+ return true;
}
- final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
- return DateFormat.format(pattern, time);
+ return false;
}
// ==== Built-in system conditions ====
@@ -775,17 +786,24 @@
public static final String COUNTDOWN_PATH = "countdown";
- public static Uri toCountdownConditionId(long time) {
+ public static final String IS_ALARM_PATH = "alarm";
+
+ /**
+ * Converts countdown condition parameters into a condition id.
+ */
+ public static Uri toCountdownConditionId(long time, boolean alarm) {
return new Uri.Builder().scheme(Condition.SCHEME)
.authority(SYSTEM_AUTHORITY)
.appendPath(COUNTDOWN_PATH)
.appendPath(Long.toString(time))
+ .appendPath(IS_ALARM_PATH)
+ .appendPath(Boolean.toString(alarm))
.build();
}
public static long tryParseCountdownConditionId(Uri conditionId) {
if (!Condition.isValidId(conditionId, SYSTEM_AUTHORITY)) return 0;
- if (conditionId.getPathSegments().size() != 2
+ if (conditionId.getPathSegments().size() < 2
|| !COUNTDOWN_PATH.equals(conditionId.getPathSegments().get(0))) return 0;
try {
return Long.parseLong(conditionId.getPathSegments().get(1));
@@ -795,10 +813,32 @@
}
}
+ /**
+ * Returns whether this condition is a countdown condition.
+ */
public static boolean isValidCountdownConditionId(Uri conditionId) {
return tryParseCountdownConditionId(conditionId) != 0;
}
+ /**
+ * Returns whether this condition is a countdown to an alarm.
+ */
+ public static boolean isValidCountdownToAlarmConditionId(Uri conditionId) {
+ if (tryParseCountdownConditionId(conditionId) != 0) {
+ if (conditionId.getPathSegments().size() < 4
+ || !IS_ALARM_PATH.equals(conditionId.getPathSegments().get(2))) {
+ return false;
+ }
+ try {
+ return Boolean.parseBoolean(conditionId.getPathSegments().get(3));
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error parsing countdown alarm condition: " + conditionId, e);
+ return false;
+ }
+ }
+ return false;
+ }
+
// ==== Built-in system condition: schedule ====
public static final String SCHEDULE_PATH = "schedule";
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index eff52e6..fb6f637 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -30,5 +30,6 @@
void dispatchPointer(in MotionEvent event);
void dispatchWallpaperCommand(String action, int x, int y,
int z, in Bundle extras);
+ void requestWallpaperColors();
void destroy();
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 424967f..65d66dc 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -105,6 +105,7 @@
private static final int MSG_WINDOW_RESIZED = 10030;
private static final int MSG_WINDOW_MOVED = 10035;
private static final int MSG_TOUCH_EVENT = 10040;
+ private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
private final ArrayList<Engine> mActiveEngines
= new ArrayList<Engine>();
@@ -268,7 +269,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (event instanceof MotionEvent
@@ -626,8 +627,7 @@
}
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
mCaller.sendMessage(msg);
- } else {
- event.recycle();
+ } else {event.recycle();
}
}
@@ -1192,6 +1192,11 @@
}
}
+ public void requestWallpaperColors() {
+ Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
+ mCaller.sendMessage(msg);
+ }
+
public void destroy() {
Message msg = mCaller.obtainMessage(DO_DETACH);
mCaller.sendMessage(msg);
@@ -1210,7 +1215,6 @@
mEngine = engine;
mActiveEngines.add(engine);
engine.attach(this);
- engine.notifyColorsChanged();
return;
}
case DO_DETACH: {
@@ -1268,6 +1272,16 @@
}
ev.recycle();
} break;
+ case MSG_REQUEST_WALLPAPER_COLORS: {
+ if (mConnection == null) {
+ break;
+ }
+ try {
+ mConnection.onWallpaperColorsChanged(mEngine.onComputeColors());
+ } catch (RemoteException e) {
+ // Connection went away, nothing to do in here.
+ }
+ } break;
default :
Log.w(TAG, "Unknown message type " + message.what);
}
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index 029f66e..ed58390 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -64,19 +64,17 @@
private final int mWeight;
private final boolean mIsItalic;
private Uri mUri;
- private final String mFallbackFor;
/**
* @hide
*/
public Font(@NonNull String fontName, int ttcIndex, @NonNull FontVariationAxis[] axes,
- int weight, boolean isItalic, String fallbackFor) {
+ int weight, boolean isItalic) {
mFontName = fontName;
mTtcIndex = ttcIndex;
mAxes = axes;
mWeight = weight;
mIsItalic = isItalic;
- mFallbackFor = fallbackFor;
}
/**
@@ -127,10 +125,6 @@
public void setUri(@NonNull Uri uri) {
mUri = uri;
}
-
- public String getFallbackFor() {
- return mFallbackFor;
- }
}
/**
diff --git a/core/java/android/text/InputFilter.java b/core/java/android/text/InputFilter.java
index d773158..a507f2b 100644
--- a/core/java/android/text/InputFilter.java
+++ b/core/java/android/text/InputFilter.java
@@ -16,7 +16,9 @@
package android.text;
-import android.annotation.Nullable;
+import android.annotation.NonNull;
+
+import com.android.internal.util.Preconditions;
import java.util.Locale;
@@ -64,7 +66,8 @@
* Constructs a locale-specific AllCaps filter, to make sure capitalization rules of that
* locale are used for transforming the sequence.
*/
- public AllCaps(@Nullable Locale locale) {
+ public AllCaps(@NonNull Locale locale) {
+ Preconditions.checkNotNull(locale);
mLocale = locale;
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 440c88e..3e64af4 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -484,6 +484,14 @@
}
/**
+ * @return interned string if it's null.
+ * @hide
+ */
+ public static String safeIntern(String s) {
+ return (s != null) ? s.intern() : null;
+ }
+
+ /**
* Returns the length that the specified CharSequence would have if
* spaces and ASCII control characters were trimmed from the start and end,
* as by {@link String#trim}.
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index 3a3646b..c17cfd5 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -70,7 +70,11 @@
TextAppearance_textSize, -1);
mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0);
- mTypeface = a.getFont(com.android.internal.R.styleable.TextAppearance_fontFamily);
+ if (!context.isRestricted() && context.canLoadUnsafeResources()) {
+ mTypeface = a.getFont(com.android.internal.R.styleable.TextAppearance_fontFamily);
+ } else {
+ mTypeface = null;
+ }
if (mTypeface != null) {
mFamilyName = null;
} else {
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index 0122e49..6342c8b 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -214,10 +214,10 @@
* Gets the last modified time of the atomic file.
* {@hide}
*
- * @return last modified time in milliseconds since epoch.
- * @throws IOException
+ * @return last modified time in milliseconds since epoch. Returns zero if
+ * the file does not exist or an I/O error is encountered.
*/
- public long getLastModifiedTime() throws IOException {
+ public long getLastModifiedTime() {
if (mBackupName.exists()) {
return mBackupName.lastModified();
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 263d3ff..9778893 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -726,17 +726,6 @@
}
/**
- * Returns the rotation associated with this display as used during layout. This is currently
- * derived from the {@link Configuration}.
- *
- * @hide
- */
- @Surface.Rotation
- public int getLayoutRotation() {
- return mResources.getConfiguration().getRotation();
- }
-
- /**
* @deprecated use {@link #getRotation}
* @return orientation of this display.
*/
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 48e5ca9..af26a88 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -193,6 +193,8 @@
private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
// check for user specified next focus
View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
+ View cycleCheck = userSetNextFocus;
+ boolean cycleStep = true; // we want the first toggle to yield false
while (userSetNextFocus != null) {
if (userSetNextFocus.isFocusable()
&& userSetNextFocus.getVisibility() == View.VISIBLE
@@ -201,6 +203,14 @@
return userSetNextFocus;
}
userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
+ if (cycleStep = !cycleStep) {
+ cycleCheck = cycleCheck.findUserSetNextFocus(root, direction);
+ if (cycleCheck == userSetNextFocus) {
+ // found a cycle, user-specified focus forms a loop and none of the views
+ // are currently focusable.
+ break;
+ }
+ }
}
return null;
}
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 20ab539..c566a65 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -111,9 +111,10 @@
* to indicate whether the event was handled. No new input events will be received
* until {@link #finishInputEvent} is called.
*
+ * @param displayId The display id on which input event triggered.
* @param event The input event that was received.
*/
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
finishInputEvent(event, false);
}
@@ -180,9 +181,9 @@
// Called from native code.
@SuppressWarnings("unused")
- private void dispatchInputEvent(int seq, InputEvent event) {
+ private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
mSeqMap.put(event.getSequenceNumber(), seq);
- onInputEvent(event);
+ onInputEvent(event, displayId);
}
// Called from native code.
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ecfc0b6..78cdf5d 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -135,17 +135,11 @@
public static final int SCALING_MODE_NO_SCALE_CROP = 3;
/** @hide */
- @IntDef({ROTATION_UNDEFINED, ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+ @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
@Retention(RetentionPolicy.SOURCE)
public @interface Rotation {}
/**
- * Rotation constant: undefined
- * @hide
- */
- public static final int ROTATION_UNDEFINED = -1;
-
- /**
* Rotation constant: 0 degree rotation (natural orientation)
*/
public static final int ROTATION_0 = 0;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 22329f4..1a2968f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -65,7 +65,8 @@
private static native void nativeSetSize(long nativeObject, int w, int h);
private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
private static native void nativeSetAlpha(long nativeObject, float alpha);
- private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
+ private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+ float dtdy, float dsdy);
private static native void nativeSetFlags(long nativeObject, int flags, int mask);
private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
@@ -272,6 +273,15 @@
public static final int POWER_MODE_DOZE_SUSPEND = 3;
/**
+ * A value for windowType used to indicate that the window should be omitted from screenshots
+ * and display mirroring. A temporary workaround until we express such things with
+ * the hierarchy.
+ * TODO: b/64227542
+ * @hide
+ */
+ public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
+
+ /**
* Create a surface with a name.
* <p>
* The surface creation flags specify what kind of surface to create and
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index cac27af..1d206ab 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,7 +16,6 @@
package android.view;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
@@ -872,31 +871,6 @@
return callbacks;
}
- /**
- * This method still exists only for compatibility reasons because some applications have relied
- * on this method via reflection. See Issue 36345857 for details.
- *
- * @deprecated No platform code is using this method anymore.
- * @hide
- */
- @Deprecated
- public void setWindowType(int type) {
- if (getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
- throw new UnsupportedOperationException(
- "SurfaceView#setWindowType() has never been a public API.");
- }
-
- if (type == TYPE_APPLICATION_PANEL) {
- Log.e(TAG, "If you are calling SurfaceView#setWindowType(TYPE_APPLICATION_PANEL) "
- + "just to make the SurfaceView to be placed on top of its window, you must "
- + "call setZOrderOnTop(true) instead.", new Throwable());
- setZOrderOnTop(true);
- return;
- }
- Log.e(TAG, "SurfaceView#setWindowType(int) is deprecated and now does nothing. "
- + "type=" + type, new Throwable());
- }
-
private void runOnUiThread(Runnable runnable) {
Handler handler = getHandler();
if (handler != null && handler.getLooper() != Looper.myLooper()) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6af01f66..eea692a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9711,6 +9711,7 @@
* @param hasTransientState true if this view has transient state
*/
public void setHasTransientState(boolean hasTransientState) {
+ final boolean oldHasTransientState = hasTransientState();
mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
mTransientStateCount - 1;
if (mTransientStateCount < 0) {
@@ -9722,9 +9723,10 @@
// update flag if we've just incremented up from 0 or decremented down to 0
mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
(hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
- if (mParent != null) {
+ final boolean newHasTransientState = hasTransientState();
+ if (mParent != null && newHasTransientState != oldHasTransientState) {
try {
- mParent.childHasTransientStateChanged(this, hasTransientState);
+ mParent.childHasTransientStateChanged(this, newHasTransientState);
} catch (AbstractMethodError e) {
Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
" does not fully implement ViewParent", e);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 05f9da5..6bf4845 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6752,7 +6752,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
enqueueInputEvent(event, this, 0, true);
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 4041bcf..1e50a85 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -992,21 +992,24 @@
@Deprecated
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
- /** Window flag: when set the window will cause the keyguard to
- * be dismissed, only if it is not a secure lock keyguard. Because such
- * a keyguard is not needed for security, it will never re-appear if
- * the user navigates to another window (in contrast to
- * {@link #FLAG_SHOW_WHEN_LOCKED}, which will only temporarily
- * hide both secure and non-secure keyguards but ensure they reappear
- * when the user moves to another UI that doesn't hide them).
- * If the keyguard is currently active and is secure (requires an
- * unlock credential) than the user will still need to confirm it before
- * seeing this window, unless {@link #FLAG_SHOW_WHEN_LOCKED} has
- * also been set.
- * @deprecated Use {@link #FLAG_SHOW_WHEN_LOCKED} or {@link KeyguardManager#dismissKeyguard}
- * instead. Since keyguard was dismissed all the time as long as an activity with this flag
- * on its window was focused, keyguard couldn't guard against unintentional touches on the
- * screen, which isn't desired.
+ /**
+ * Window flag: when set the window will cause the keyguard to be
+ * dismissed, only if it is not a secure lock keyguard. Because such a
+ * keyguard is not needed for security, it will never re-appear if the
+ * user navigates to another window (in contrast to
+ * {@link #FLAG_SHOW_WHEN_LOCKED}, which will only temporarily hide both
+ * secure and non-secure keyguards but ensure they reappear when the
+ * user moves to another UI that doesn't hide them). If the keyguard is
+ * currently active and is secure (requires an unlock credential) than
+ * the user will still need to confirm it before seeing this window,
+ * unless {@link #FLAG_SHOW_WHEN_LOCKED} has also been set.
+ *
+ * @deprecated Use {@link #FLAG_SHOW_WHEN_LOCKED} or
+ * {@link KeyguardManager#requestDismissKeyguard} instead.
+ * Since keyguard was dismissed all the time as long as an
+ * activity with this flag on its window was focused,
+ * keyguard couldn't guard against unintentional touches on
+ * the screen, which isn't desired.
*/
@Deprecated
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
@@ -1413,11 +1416,12 @@
public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;
/**
- * Flag to indicate that this window should be ignored when determining what parts of the
- * screen can be magnified.
+ * Indicates that this window is the rounded corners overlay present on some
+ * devices this means that it will be excluded from: screenshots,
+ * screen magnification, and mirroring.
* @hide
*/
- public static final int PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT = 0x00100000;
+ public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
/**
* Control flags that are private to the platform.
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 4c9cf40..98f8dc8 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -347,4 +347,11 @@
* Requests the window manager to recompute the windows for accessibility.
*/
public abstract void computeWindowsForAccessibility();
+
+ /**
+ * Called after virtual display Id is updated by
+ * {@link com.android.server.vr.Vr2dDisplay} with a specific
+ * {@param vr2dDisplayId}.
+ */
+ public abstract void setVr2dDisplayId(int vr2dDisplayId);
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 668d25e..49b7ed8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -616,7 +617,16 @@
* 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
* copy() must be made and the copy must be recycled.
**/
- public void onPointerEvent(MotionEvent motionEvent);
+ void onPointerEvent(MotionEvent motionEvent);
+
+ /**
+ * @see #onPointerEvent(MotionEvent)
+ **/
+ default void onPointerEvent(MotionEvent motionEvent, int displayId) {
+ if (displayId == DEFAULT_DISPLAY) {
+ onPointerEvent(motionEvent);
+ }
+ }
}
/** Window has been added to the screen. */
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 4f9f7e1..29e5523 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -52,9 +52,64 @@
import java.util.Objects;
/**
- * App entry point to the Autofill Framework.
+ * The {@link AutofillManager} provides ways for apps and custom views to integrate with the
+ * Autofill Framework lifecycle.
*
- * <p>It is safe to call into this from any thread.
+ * <p>The autofill lifecycle starts with the creation of an autofill context associated with an
+ * activity context; the autofill context is created when one of the following methods is called for
+ * the first time in an activity context, and the current user has an enabled autofill service:
+ *
+ * <ul>
+ * <li>{@link #notifyViewEntered(View)}
+ * <li>{@link #notifyViewEntered(View, int, Rect)}
+ * <li>{@link #requestAutofill(View)}
+ * </ul>
+ *
+ * <p>Tipically, the context is automatically created when the first view of the activity is
+ * focused because {@code View.onFocusChanged()} indirectly calls
+ * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to
+ * explicitly create it (for example, a custom view developer could offer a contextual menu action
+ * in a text-field view to let users manually request autofill).
+ *
+ * <p>After the context is created, the Android System creates a {@link android.view.ViewStructure}
+ * that represents the view hierarchy by calling
+ * {@link View#dispatchProvideAutofillStructure(android.view.ViewStructure, int)} in the root views
+ * of all application windows. By default, {@code dispatchProvideAutofillStructure()} results in
+ * subsequent calls to {@link View#onProvideAutofillStructure(android.view.ViewStructure, int)} and
+ * {@link View#onProvideAutofillVirtualStructure(android.view.ViewStructure, int)} for each view in
+ * the hierarchy.
+ *
+ * <p>The resulting {@link android.view.ViewStructure} is then passed to the autofill service, which
+ * parses it looking for views that can be autofilled. If the service finds such views, it returns
+ * a data structure to the Android System containing the following optional info:
+ *
+ * <ul>
+ * <li>Datasets used to autofill subsets of views in the activity.
+ * <li>Id of views that the service can save their values for future autofilling.
+ * </ul>
+ *
+ * <p>When the service returns datasets, the Android System displays an autofill dataset picker
+ * UI affordance associated with the view, when the view is focused on and is part of a dataset.
+ * The application can be notified when the affordance is shown by registering an
+ * {@link AutofillCallback} through {@link #registerCallback(AutofillCallback)}. When the user
+ * selects a dataset from the affordance, all views present in the dataset are autofilled, through
+ * calls to {@link View#autofill(AutofillValue)} or {@link View#autofill(SparseArray)}.
+ *
+ * <p>When the service returns ids of savable views, the Android System keeps track of changes
+ * made to these views, so they can be used to determine if the autofill save UI is shown later.
+ *
+ * <p>The context is then finished when one of the following occurs:
+ *
+ * <ul>
+ * <li>{@link #commit()} is called or all savable views are gone.
+ * <li>{@link #cancel()} is called.
+ * </ul>
+ *
+ * <p>Finally, after the autofill context is commited (i.e., not cancelled), the Android System
+ * shows a save UI affordance if the value of savable views have changed. If the user selects the
+ * option to Save, the current value of the views is then sent to the autofill service.
+ *
+ * <p>It is safe to call into its methods from any thread.
*/
@SystemService(Context.AUTOFILL_MANAGER_SERVICE)
public final class AutofillManager {
@@ -694,8 +749,13 @@
/**
* Called to indicate the current autofill context should be commited.
*
- * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
- * call this method after the form is submitted and another page is rendered.
+ * <p>This method is typically called by {@link View Views} that manage virtual views; for
+ * example, when the view is rendering an {@code HTML} page with a form and virtual views
+ * that represent the HTML elements, it should call this method after the form is submitted and
+ * another page is rendered.
+ *
+ * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+ * methods such as {@link android.app.Activity#finish()}.
*/
public void commit() {
if (!hasAutofillFeature()) {
@@ -713,8 +773,13 @@
/**
* Called to indicate the current autofill context should be cancelled.
*
- * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
- * call this method if the user does not post the form but moves to another form in this page.
+ * <p>This method is typically called by {@link View Views} that manage virtual views; for
+ * example, when the view is rendering an {@code HTML} page with a form and virtual views
+ * that represent the HTML elements, it should call this method if the user does not post the
+ * form but moves to another form in this page.
+ *
+ * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+ * methods such as {@link android.app.Activity#finish()}.
*/
public void cancel() {
if (!hasAutofillFeature()) {
@@ -1484,10 +1549,10 @@
}
/**
- * Callback for auto-fill related events.
+ * Callback for autofill related events.
*
* <p>Typically used for applications that display their own "auto-complete" views, so they can
- * enable / disable such views when the auto-fill UI affordance is shown / hidden.
+ * enable / disable such views when the autofill UI affordance is shown / hidden.
*/
public abstract static class AutofillCallback {
@@ -1497,7 +1562,7 @@
public @interface AutofillEventType {}
/**
- * The auto-fill input UI affordance associated with the view was shown.
+ * The autofill input UI affordance associated with the view was shown.
*
* <p>If the view provides its own auto-complete UI affordance and its currently shown, it
* should be hidden upon receiving this event.
@@ -1505,7 +1570,7 @@
public static final int EVENT_INPUT_SHOWN = 1;
/**
- * The auto-fill input UI affordance associated with the view was hidden.
+ * The autofill input UI affordance associated with the view was hidden.
*
* <p>If the view provides its own auto-complete UI affordance that was hidden upon a
* {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
@@ -1513,7 +1578,7 @@
public static final int EVENT_INPUT_HIDDEN = 2;
/**
- * The auto-fill input UI affordance associated with the view won't be shown because
+ * The autofill input UI affordance associated with the view isn't shown because
* autofill is not available.
*
* <p>If the view provides its own auto-complete UI affordance but was not displaying it
diff --git a/core/java/android/view/textclassifier/LangId.java b/core/java/android/view/textclassifier/LangId.java
deleted file mode 100644
index 23c7842..0000000
--- a/core/java/android/view/textclassifier/LangId.java
+++ /dev/null
@@ -1,69 +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.
- */
-package android.view.textclassifier;
-
-/**
- * Java wrapper for LangId native library interface.
- * This class is used to detect languages in text.
- */
-final class LangId {
-
- static {
- System.loadLibrary("textclassifier");
- }
-
- private final long mModelPtr;
-
- /**
- * Creates a new instance of LangId predictor, using the provided model image.
- */
- LangId(int fd) {
- mModelPtr = nativeNew(fd);
- }
-
- /**
- * Detects the language for given text.
- */
- public ClassificationResult[] findLanguages(String text) {
- return nativeFindLanguages(mModelPtr, text);
- }
-
- /**
- * Frees up the allocated memory.
- */
- public void close() {
- nativeClose(mModelPtr);
- }
-
- private static native long nativeNew(int fd);
-
- private static native ClassificationResult[] nativeFindLanguages(
- long context, String text);
-
- private static native void nativeClose(long context);
-
- /** Classification result for findLanguage method. */
- static final class ClassificationResult {
- final String mLanguage;
- /** float range: 0 - 1 */
- final float mScore;
-
- ClassificationResult(String language, float score) {
- mLanguage = language;
- mScore = score;
- }
- }
-}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index efc88e2..d7b0776 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -16,37 +16,22 @@
package android.view.textclassifier;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
import com.android.internal.util.Preconditions;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
/**
* Interface to the text classification service.
*/
@SystemService(Context.TEXT_CLASSIFICATION_SERVICE)
public final class TextClassificationManager {
- private static final String LOG_TAG = "TextClassificationManager";
-
private final Object mTextClassifierLock = new Object();
- private final Object mLangIdLock = new Object();
private final Context mContext;
- private ParcelFileDescriptor mLangIdFd;
private TextClassifier mTextClassifier;
- private LangId mLangId;
/** @hide */
public TextClassificationManager(Context context) {
@@ -75,47 +60,4 @@
mTextClassifier = textClassifier;
}
}
-
- /**
- * Returns information containing languages that were detected in the provided text.
- * This is a blocking operation you should avoid calling it on the UI thread.
- *
- * @throws IllegalArgumentException if text is null
- * @hide
- */
- public List<TextLanguage> detectLanguages(@NonNull CharSequence text) {
- Preconditions.checkArgument(text != null);
- try {
- if (text.length() > 0) {
- final LangId.ClassificationResult[] results =
- getLanguageDetector().findLanguages(text.toString());
- final TextLanguage.Builder tlBuilder = new TextLanguage.Builder(0, text.length());
- final int size = results.length;
- for (int i = 0; i < size; i++) {
- tlBuilder.setLanguage(
- new Locale.Builder().setLanguageTag(results[i].mLanguage).build(),
- results[i].mScore);
- }
-
- return Collections.unmodifiableList(Arrays.asList(tlBuilder.build()));
- }
- } catch (Throwable t) {
- // Avoid throwing from this method. Log the error.
- Log.e(LOG_TAG, "Error detecting languages for text. Returning empty result.", t);
- }
- // Getting here means something went wrong. Return an empty result.
- return Collections.emptyList();
- }
-
- private LangId getLanguageDetector() throws FileNotFoundException {
- synchronized (mLangIdLock) {
- if (mLangId == null) {
- mLangIdFd = ParcelFileDescriptor.open(
- new File("/etc/textclassifier/textclassifier.langid.model"),
- ParcelFileDescriptor.MODE_READ_ONLY);
- mLangId = new LangId(mLangIdFd.getFd());
- }
- return mLangId;
- }
- }
}
diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java
deleted file mode 100644
index 209813a..0000000
--- a/core/java/android/view/textclassifier/TextLanguage.java
+++ /dev/null
@@ -1,140 +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.
- */
-
-package android.view.textclassifier;
-
-import android.annotation.FloatRange;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Specifies detected languages for a section of text indicated by a start and end index.
- * @hide
- */
-public final class TextLanguage {
-
- private final int mStartIndex;
- private final int mEndIndex;
- @NonNull private final EntityConfidence<Locale> mLanguageConfidence;
- @NonNull private final List<Locale> mLanguages;
-
- private TextLanguage(
- int startIndex, int endIndex, @NonNull EntityConfidence<Locale> languageConfidence) {
- mStartIndex = startIndex;
- mEndIndex = endIndex;
- mLanguageConfidence = new EntityConfidence<>(languageConfidence);
- mLanguages = mLanguageConfidence.getEntities();
- }
-
- /**
- * Returns the start index of the detected languages in the text provided to generate this
- * object.
- */
- public int getStartIndex() {
- return mStartIndex;
- }
-
- /**
- * Returns the end index of the detected languages in the text provided to generate this object.
- */
- public int getEndIndex() {
- return mEndIndex;
- }
-
- /**
- * Returns the number of languages found in the classified text.
- */
- @IntRange(from = 0)
- public int getLanguageCount() {
- return mLanguages.size();
- }
-
- /**
- * Returns the language locale at the specified index.
- * Language locales are ordered from high confidence to low confidence.
- *
- * @throws IndexOutOfBoundsException if the specified index is out of range.
- * @see #getLanguageCount() for the number of language locales available.
- */
- @NonNull
- public Locale getLanguage(int index) {
- return mLanguages.get(index);
- }
-
- /**
- * Returns the confidence score for the specified language. The value ranges from
- * 0 (low confidence) to 1 (high confidence). 0 indicates that the language was
- * not found for the classified text.
- */
- @FloatRange(from = 0.0, to = 1.0)
- public float getConfidenceScore(@Nullable Locale language) {
- return mLanguageConfidence.getConfidenceScore(language);
- }
-
- @Override
- public String toString() {
- return String.format("TextLanguage {%d, %d, %s}",
- mStartIndex, mEndIndex, mLanguageConfidence);
- }
-
- /**
- * Builder to build {@link TextLanguage} objects.
- */
- public static final class Builder {
-
- private final int mStartIndex;
- private final int mEndIndex;
- @NonNull private final EntityConfidence<Locale> mLanguageConfidence =
- new EntityConfidence<>();
-
- /**
- * Creates a builder to build {@link TextLanguage} objects.
- *
- * @param startIndex the start index of the detected languages in the text provided
- * to generate the result
- * @param endIndex the end index of the detected languages in the text provided
- * to generate the result. Must be greater than startIndex
- */
- public Builder(@IntRange(from = 0) int startIndex, @IntRange(from = 0) int endIndex) {
- Preconditions.checkArgument(startIndex >= 0);
- Preconditions.checkArgument(endIndex > startIndex);
- mStartIndex = startIndex;
- mEndIndex = endIndex;
- }
-
- /**
- * Sets a language locale with the associated confidence score.
- */
- public Builder setLanguage(
- @NonNull Locale locale, @FloatRange(from = 0.0, to = 1.0) float confidenceScore) {
- mLanguageConfidence.setEntityType(locale, confidenceScore);
- return this;
- }
-
- /**
- * Builds and returns a {@link TextLanguage}.
- */
- public TextLanguage build() {
- return new TextLanguage(mStartIndex, mEndIndex, mLanguageConfidence);
- }
- }
-}
diff --git a/core/java/android/webkit/SafeBrowsingResponse.java b/core/java/android/webkit/SafeBrowsingResponse.java
index 3540f80..2ccd2ba 100644
--- a/core/java/android/webkit/SafeBrowsingResponse.java
+++ b/core/java/android/webkit/SafeBrowsingResponse.java
@@ -18,9 +18,9 @@
/**
* Used to indicate an action to take when hitting a malicious URL. Instances of this class are
- * created by the WebView and passed to {@link WebViewClient#onSafebrowsingHit}. The host
- * application must call {@link #showInterstitial}, {@link #proceed}, or {@link #backToSafety} to
- * set the WebView's response to the Safe Browsing hit.
+ * created by the WebView and passed to {@link android.webkit.WebViewClient#onSafeBrowsingHit}. The
+ * host application must call {@link #showInterstitial(boolean)}, {@link #proceed(boolean)}, or
+ * {@link #backToSafety(boolean)} to set the WebView's response to the Safe Browsing hit.
*/
public abstract class SafeBrowsingResponse {
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 3a6de96..82cff7c 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1390,17 +1390,15 @@
* Sets whether Safe Browsing is enabled. Safe browsing allows WebView to
* protect against malware and phishing attacks by verifying the links.
*
- * Safe browsing is disabled by default. The recommended way to enable
- * Safe browsing is using a manifest tag to change the default value to
- * enabled for all WebViews.
* <p>
- * <pre>
- * <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
- * android:value="true" />
- * </pre>
+ * Safe browsing is disabled by default. The recommended way to enable Safe browsing is using a
+ * manifest tag to change the default value to enabled for all WebViews (read <a
+ * href="{@docRoot}reference/android/webkit/WebView.html">general Safe Browsing info</a>).
* </p>
*
+ * <p>
* This API overrides the manifest tag value for this WebView.
+ * </p>
*
* @param enabled Whether Safe browsing is enabled.
*/
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 333c44c..dd716eb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -319,6 +319,22 @@
* out.
* </p>
*
+ * <h3>Safe Browsing</h3>
+ *
+ * <p>
+ * If Safe Browsing is enabled, WebView will block malicious URLs and present a warning UI to the
+ * user to allow them to navigate back safely or proceed to the malicious page.
+ * </p>
+ * <p>
+ * The recommended way for apps to enable the feature is putting the following tag in the manifest:
+ * </p>
+ * <p>
+ * <pre>
+ * <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
+ * android:value="true" />
+ * </pre>
+ * </p>
+ *
*/
// Implementation notes.
// The WebView is a thin API class that delegates its public API to a backend WebViewProvider
@@ -1622,8 +1638,24 @@
}
/**
- * Starts Safe Browsing initialization. This should only be called once. This does not require
- * an Activity Context, and will always use the application Context to do its work.
+ * Starts Safe Browsing initialization. This should only be called once.
+ *
+ * <p>
+ * Because the Safe Browsing feature takes time to initialize, WebView may temporarily whitelist
+ * URLs until the feature is ready. The callback will be invoked with true once initialization
+ * is complete.
+ * </p>
+ *
+ * <p>
+ * This does not enable the Safe Browsing feature itself, and should only be used if the feature
+ * is otherwise enabled.
+ * </p>
+ *
+ * <p>
+ * This does not require an Activity Context, and will always use the application Context to do
+ * its work.
+ * </p>
+ *
* @param context Application Context.
* @param callback will be called with the value true if initialization is
* successful. The callback will be run on the UI thread.
@@ -1633,7 +1665,9 @@
}
/**
- * Shuts down Safe Browsing. This should only be called once.
+ * Shuts down Safe Browsing. This should only be called once. This does not disable the feature,
+ * it only frees resources used by Safe Browsing code. To disable Safe Browsing on an individual
+ * WebView, see {@link WebSettings#setSafeBrowsingEnabled}
*/
public static void shutdownSafeBrowsing() {
getFactory().getStatics().shutdownSafeBrowsing();
@@ -1642,12 +1676,23 @@
/**
* Sets the list of domains that are exempt from SafeBrowsing checks. The list is
* global for all the WebViews.
- * TODO: Add documentation for the format of the urls.
+ * <p>
+ * Each rule should take one of these:
+ * <table>
+ * <tr><th> Rule </th> <th> Example </th> <th> Matches Subdomain</th> </tr>
+ * <tr><th> HOSTNAME </th> <th> example.com </th> <th> Yes </th> </tr>
+ * <tr><th>.HOSTNAME</th> <th> .example.com </th> <th> No </th> </tr>
+ * <tr><th> IPV4_LITERAL </th> <th> 192.168.1.1 </th> <th> No </th></tr>
+ * <tr><th> IPV6_LITERAL_WITH_BRACKETS</th><th>[10:20:30:40:50:60:70:80]</th><th>No</th></tr>
+ * </table>
+ * <p>
+ * All other rules, including wildcards, are invalid.
+ * <p>
*
* @param urls the list of URLs
- * @param callback will be called with true if URLs are successfully added to the whitelist. It
- * will be called with false if any URLs are malformed. The callback will be run on the UI
- * thread.
+ * @param callback will be called with true if URLs are successfully added to the whitelist.
+ * It will be called with false if any URLs are malformed. The callback will be run on
+ * the UI thread
*/
public static void setSafeBrowsingWhitelist(@NonNull List<String> urls,
@Nullable ValueCallback<Boolean> callback) {
@@ -2289,7 +2334,6 @@
/**
* Sets the {@link TextClassifier} for this WebView.
- * @hide
*/
public void setTextClassifier(@Nullable TextClassifier textClassifier) {
mProvider.setTextClassifier(textClassifier);
@@ -2298,7 +2342,6 @@
/**
* Returns the {@link TextClassifier} used by this WebView.
* If no TextClassifier has been set, this WebView uses the default set by the system.
- * @hide
*/
@NonNull
public TextClassifier getTextClassifier() {
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 452ff17..634cbe3 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.widget.RemoteViews.RemoteView;
@@ -54,7 +55,7 @@
* }
* }</pre>
*
- * <p>The above snippet creates an instance of {@link View.OnClickListener} and wires
+ * <p>The above snippet creates an instance of {@link android.view.View.OnClickListener} and wires
* the listener to the button using
* {@link #setOnClickListener setOnClickListener(View.OnClickListener)}.
* As a result, the system executes the code you write in {@code onClick(View)} after the
@@ -77,15 +78,8 @@
* {@link android.R.styleable#Button Button Attributes},
* {@link android.R.styleable#TextView TextView Attributes},
* {@link android.R.styleable#View View Attributes}. See the
- * {@link <a href="{@docRoot}guide/topics/ui/themes.html#ApplyingStyles">Styles and Themes</a>
+ * <a href="{@docRoot}guide/topics/ui/themes.html#ApplyingStyles">Styles and Themes</a>
* guide to learn how to implement and organize overrides to style-related attributes.</p>
- *
- * @see
- * <a href="{@docRoot}guide/topics/ui/controls/button.html">Buttons Guide</a>
- * {@link android.R.styleable#Button Styleable Button Attributes},
- * {@link android.R.styleable#TextView Styleable TextView Attributes},
- * {@link android.R.styleable#View Styleable View Attributes},
- *
*/
@RemoteView
public class Button extends TextView {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 88c3c5b..380bf7a 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -66,7 +66,7 @@
* both horizontal and vertical alignment of all child views within the single row or column.</p>
*
* <p>You can set
- * {@link LinearLayout.LayoutParams.html#attr_android:layout_weight android:layout_weight}
+ * {@link android.R.styleable#LinearLayout_Layout_layout_weight android:layout_weight}
* on individual child views to specify how linear layout divides remaining space amongst
* the views it contains. See the
* <a href="https://developer.android.com/guide/topics/ui/layout/linear.html">Linear Layout</a>
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 69edbbb..b2e2e88 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8341,7 +8341,9 @@
}
private boolean suggestedSizeFitsInSpace(int suggestedSizeInPx, RectF availableSpace) {
- final CharSequence text = getText();
+ final CharSequence text = mTransformed != null
+ ? mTransformed
+ : getText();
final int maxLines = getMaxLines();
if (mTempTextPaint == null) {
mTempTextPaint = new TextPaint();
@@ -10320,7 +10322,16 @@
return;
}
- setText(value.getTextValue(), mBufferType, true, 0);
+ final CharSequence autofilledValue = value.getTextValue();
+
+ // First autofill it...
+ setText(autofilledValue, mBufferType, true, 0);
+
+ // ...then move cursor to the end.
+ final CharSequence text = getText();
+ if ((text instanceof Spannable)) {
+ Selection.setSelection((Spannable) text, text.length());
+ }
}
@Override
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialog.java b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
index 47d2a9c..7108d14 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
@@ -24,6 +24,7 @@
import android.media.MediaRouter.RouteInfo;
import android.os.Bundle;
import android.text.TextUtils;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -130,7 +131,8 @@
// Must be called after setContentView.
getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
- R.drawable.ic_media_route_off_holo_dark);
+ isLightTheme(getContext()) ? R.drawable.ic_media_route_off_holo_light
+ : R.drawable.ic_media_route_off_holo_dark);
mAdapter = new RouteAdapter(getContext());
mListView = (ListView)findViewById(R.id.media_route_list);
@@ -176,6 +178,12 @@
}
}
+ static boolean isLightTheme(Context context) {
+ TypedValue value = new TypedValue();
+ return context.getTheme().resolveAttribute(R.attr.isLightTheme, value, true)
+ && value.data != 0;
+ }
+
private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
implements ListView.OnItemClickListener {
private final LayoutInflater mInflater;
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index 237feed..3cbc9ea 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -43,8 +43,12 @@
* </p>
*/
public MediaRouteChooserDialogFragment() {
+ int theme = MediaRouteChooserDialog.isLightTheme(getContext())
+ ? android.R.style.Theme_DeviceDefault_Light_Dialog
+ : android.R.style.Theme_DeviceDefault_Dialog;
+
setCancelable(true);
- setStyle(STYLE_NORMAL, android.R.style.Theme_DeviceDefault_Dialog);
+ setStyle(STYLE_NORMAL, theme);
}
public int getRouteTypes() {
diff --git a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
index fad7fd4..bb2d7fa 100644
--- a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
+++ b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
@@ -71,16 +71,18 @@
final MediaRouter router = (MediaRouter)context.getSystemService(
Context.MEDIA_ROUTER_SERVICE);
+ int theme = MediaRouteChooserDialog.isLightTheme(context)
+ ? android.R.style.Theme_DeviceDefault_Light_Dialog
+ : android.R.style.Theme_DeviceDefault_Dialog;
+
MediaRouter.RouteInfo route = router.getSelectedRoute();
if (route.isDefault() || !route.matchesTypes(routeTypes)) {
- final MediaRouteChooserDialog d = new MediaRouteChooserDialog(
- context, android.R.style.Theme_DeviceDefault_Dialog);
+ final MediaRouteChooserDialog d = new MediaRouteChooserDialog(context, theme);
d.setRouteTypes(routeTypes);
d.setExtendedSettingsClickListener(extendedSettingsClickListener);
return d;
} else {
- MediaRouteControllerDialog d = new MediaRouteControllerDialog(
- context, android.R.style.Theme_DeviceDefault_Dialog);
+ MediaRouteControllerDialog d = new MediaRouteControllerDialog(context, theme);
return d;
}
}
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index 477285e63..ef98a5e9 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -22,6 +22,7 @@
import android.app.WallpaperManager;
import android.content.Context;
import android.os.Trace;
+import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -44,13 +45,14 @@
private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK};
private static final String TAG = "ColorExtractor";
+ private static final boolean DEBUG = false;
- private final SparseArray<GradientColors[]> mGradientColors;
+ protected final SparseArray<GradientColors[]> mGradientColors;
private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners;
private final Context mContext;
private final ExtractionType mExtractionType;
- private WallpaperColors mSystemColors;
- private WallpaperColors mLockColors;
+ protected WallpaperColors mSystemColors;
+ protected WallpaperColors mLockColors;
public ColorExtractor(Context context) {
this(context, new Tonal(context));
@@ -147,6 +149,9 @@
@Override
public void onColorsChanged(WallpaperColors colors, int which) {
+ if (DEBUG) {
+ Log.d(TAG, "New wallpaper colors for " + which + ": " + colors);
+ }
boolean changed = false;
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
mLockColors = colors;
diff --git a/core/java/com/android/internal/graphics/ColorUtils.java b/core/java/com/android/internal/graphics/ColorUtils.java
index 6c1efa4..8b2a2dc 100644
--- a/core/java/com/android/internal/graphics/ColorUtils.java
+++ b/core/java/com/android/internal/graphics/ColorUtils.java
@@ -106,6 +106,31 @@
}
/**
+ * Calculates the minimum alpha value which can be applied to {@code background} so that would
+ * have a contrast value of at least {@code minContrastRatio} when alpha blended to
+ * {@code foreground}.
+ *
+ * @param foreground the foreground color
+ * @param background the background color, opacity will be ignored
+ * @param minContrastRatio the minimum contrast ratio
+ * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+ */
+ public static int calculateMinimumBackgroundAlpha(@ColorInt int foreground,
+ @ColorInt int background, float minContrastRatio) {
+ // Ignore initial alpha that the background might have since this is
+ // what we're trying to calculate.
+ background = setAlphaComponent(background, 255);
+ final int leastContrastyColor = setAlphaComponent(foreground, 255);
+ return binaryAlphaSearch(foreground, background, minContrastRatio, (fg, bg, alpha) -> {
+ int testBackground = blendARGB(leastContrastyColor, bg, alpha/255f);
+ // Float rounding might set this alpha to something other that 255,
+ // raising an exception in calculateContrast.
+ testBackground = setAlphaComponent(testBackground, 255);
+ return calculateContrast(fg, testBackground);
+ });
+ }
+
+ /**
* Calculates the minimum alpha value which can be applied to {@code foreground} so that would
* have a contrast value of at least {@code minContrastRatio} when compared to
* {@code background}.
@@ -122,14 +147,33 @@
+ Integer.toHexString(background));
}
+ ContrastCalculator contrastCalculator = (fg, bg, alpha) -> {
+ int testForeground = setAlphaComponent(fg, alpha);
+ return calculateContrast(testForeground, bg);
+ };
+
// First lets check that a fully opaque foreground has sufficient contrast
- int testForeground = setAlphaComponent(foreground, 255);
- double testRatio = calculateContrast(testForeground, background);
+ double testRatio = contrastCalculator.calculateContrast(foreground, background, 255);
if (testRatio < minContrastRatio) {
// Fully opaque foreground does not have sufficient contrast, return error
return -1;
}
+ foreground = setAlphaComponent(foreground, 255);
+ return binaryAlphaSearch(foreground, background, minContrastRatio, contrastCalculator);
+ }
+ /**
+ * Calculates the alpha value using binary search based on a given contrast evaluation function
+ * and target contrast that needs to be satisfied.
+ *
+ * @param foreground the foreground color
+ * @param background the opaque background color
+ * @param minContrastRatio the minimum contrast ratio
+ * @param calculator function that calculates contrast
+ * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+ */
+ private static int binaryAlphaSearch(@ColorInt int foreground, @ColorInt int background,
+ float minContrastRatio, ContrastCalculator calculator) {
// Binary search to find a value with the minimum value which provides sufficient contrast
int numIterations = 0;
int minAlpha = 0;
@@ -139,9 +183,8 @@
(maxAlpha - minAlpha) > MIN_ALPHA_SEARCH_PRECISION) {
final int testAlpha = (minAlpha + maxAlpha) / 2;
- testForeground = setAlphaComponent(foreground, testAlpha);
- testRatio = calculateContrast(testForeground, background);
-
+ final double testRatio = calculator.calculateContrast(foreground, background,
+ testAlpha);
if (testRatio < minContrastRatio) {
minAlpha = testAlpha;
} else {
@@ -615,4 +658,8 @@
return result;
}
+ private interface ContrastCalculator {
+ double calculateContrast(int foreground, int background, int alpha);
+ }
+
}
\ No newline at end of file
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index df9c27b..1811800c 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -94,8 +94,8 @@
}
public boolean alwaysOnEnabled(int user) {
- return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user)
- && alwaysOnAvailable();
+ return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user) && alwaysOnAvailable()
+ && !accessibilityInversionEnabled(user);
}
public boolean alwaysOnAvailable() {
@@ -103,10 +103,18 @@
&& ambientDisplayAvailable();
}
+ public boolean alwaysOnAvailableForUser(int user) {
+ return alwaysOnAvailable() && !accessibilityInversionEnabled(user);
+ }
+
public String ambientDisplayComponent() {
return mContext.getResources().getString(R.string.config_dozeComponent);
}
+ public boolean accessibilityInversionEnabled(int user) {
+ return boolSettingDefaultOff(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, user);
+ }
+
private boolean ambientDisplayAvailable() {
return !TextUtils.isEmpty(ambientDisplayComponent());
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3599e64..611c4b8 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -119,7 +119,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 162 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 164 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS;
@@ -3632,7 +3632,12 @@
}
public void noteUidProcessStateLocked(int uid, int state) {
- uid = mapUid(uid);
+ int parentUid = mapUid(uid);
+ if (uid != parentUid) {
+ // Isolated UIDs process state is already rolled up into parent, so no need to track
+ // Otherwise the parent's process state will get downgraded incorrectly
+ return;
+ }
getUidStatsLocked(uid).updateUidProcessStateLocked(state);
}
@@ -5702,7 +5707,7 @@
LongSamplingCounter mUserCpuTime;
LongSamplingCounter mSystemCpuTime;
- LongSamplingCounter[][] mCpuClusterSpeed;
+ LongSamplingCounter[][] mCpuClusterSpeedTimesUs;
LongSamplingCounterArray mCpuFreqTimeMs;
LongSamplingCounterArray mScreenOffCpuFreqTimeMs;
@@ -6551,12 +6556,12 @@
@Override
public long getTimeAtCpuSpeed(int cluster, int step, int which) {
- if (mCpuClusterSpeed != null) {
- if (cluster >= 0 && cluster < mCpuClusterSpeed.length) {
- final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster];
- if (cpuSpeeds != null) {
- if (step >= 0 && step < cpuSpeeds.length) {
- final LongSamplingCounter c = cpuSpeeds[step];
+ if (mCpuClusterSpeedTimesUs != null) {
+ if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) {
+ final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster];
+ if (cpuSpeedTimesUs != null) {
+ if (step >= 0 && step < cpuSpeedTimesUs.length) {
+ final LongSamplingCounter c = cpuSpeedTimesUs[step];
if (c != null) {
return c.getCountLocked(which);
}
@@ -6707,8 +6712,8 @@
mUserCpuTime.reset(false);
mSystemCpuTime.reset(false);
- if (mCpuClusterSpeed != null) {
- for (LongSamplingCounter[] speeds : mCpuClusterSpeed) {
+ if (mCpuClusterSpeedTimesUs != null) {
+ for (LongSamplingCounter[] speeds : mCpuClusterSpeedTimesUs) {
if (speeds != null) {
for (LongSamplingCounter speed : speeds) {
if (speed != null) {
@@ -6897,8 +6902,8 @@
mUserCpuTime.detach();
mSystemCpuTime.detach();
- if (mCpuClusterSpeed != null) {
- for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
+ if (mCpuClusterSpeedTimesUs != null) {
+ for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
if (cpuSpeeds != null) {
for (LongSamplingCounter c : cpuSpeeds) {
if (c != null) {
@@ -7151,10 +7156,10 @@
mUserCpuTime.writeToParcel(out);
mSystemCpuTime.writeToParcel(out);
- if (mCpuClusterSpeed != null) {
+ if (mCpuClusterSpeedTimesUs != null) {
out.writeInt(1);
- out.writeInt(mCpuClusterSpeed.length);
- for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
+ out.writeInt(mCpuClusterSpeedTimesUs.length);
+ for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
if (cpuSpeeds != null) {
out.writeInt(1);
out.writeInt(cpuSpeeds.length);
@@ -7448,7 +7453,7 @@
throw new ParcelFormatException("Incompatible number of cpu clusters");
}
- mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][];
+ mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][];
for (int cluster = 0; cluster < numCpuClusters; cluster++) {
if (in.readInt() != 0) {
int numSpeeds = in.readInt();
@@ -7458,18 +7463,19 @@
}
final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
- mCpuClusterSpeed[cluster] = cpuSpeeds;
+ mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds;
for (int speed = 0; speed < numSpeeds; speed++) {
if (in.readInt() != 0) {
- cpuSpeeds[speed] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
+ cpuSpeeds[speed] = new LongSamplingCounter(
+ mBsi.mOnBatteryTimeBase, in);
}
}
} else {
- mCpuClusterSpeed[cluster] = null;
+ mCpuClusterSpeedTimesUs[cluster] = null;
}
}
} else {
- mCpuClusterSpeed = null;
+ mCpuClusterSpeedTimesUs = null;
}
mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
@@ -8038,6 +8044,7 @@
/**
* Number of times wakeup alarms have occurred for this app.
+ * On screen-off timebase starting in report v25.
*/
ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
@@ -8066,7 +8073,7 @@
mWakeupAlarms.clear();
for (int i=0; i<numWA; i++) {
String tag = in.readString();
- mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryTimeBase, in));
+ mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in));
}
int numServs = in.readInt();
@@ -8105,7 +8112,7 @@
public void noteWakeupAlarmLocked(String tag) {
Counter c = mWakeupAlarms.get(tag);
if (c == null) {
- c = new Counter(mBsi.mOnBatteryTimeBase);
+ c = new Counter(mBsi.mOnBatteryScreenOffTimeBase);
mWakeupAlarms.put(tag, c);
}
c.stepAtomic();
@@ -10424,46 +10431,48 @@
}
}
- long totalCpuClustersTime = 0;
+ long totalCpuClustersTimeMs = 0;
// Read the time spent for each cluster at various cpu frequencies.
- final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][];
+ final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][];
for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
- clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
- if (clusterSpeeds[cluster] != null) {
- for (int speed = clusterSpeeds[cluster].length - 1; speed >= 0; --speed) {
- totalCpuClustersTime += clusterSpeeds[cluster][speed];
+ clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
+ if (clusterSpeedTimesMs[cluster] != null) {
+ for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) {
+ totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed];
}
}
}
- if (totalCpuClustersTime != 0) {
+ if (totalCpuClustersTimeMs != 0) {
// We have cpu times per freq aggregated over all uids but we need the times per uid.
// So, we distribute total time spent by an uid to different cpu freqs based on the
// amount of time cpu was running at that freq.
final int updatedUidsCount = updatedUids.size();
for (int i = 0; i < updatedUidsCount; ++i) {
final Uid u = getUidStatsLocked(updatedUids.keyAt(i));
- final long appCpuTimeMs = updatedUids.valueAt(i) / 1000;
+ final long appCpuTimeUs = updatedUids.valueAt(i);
// Add the cpu speeds to this UID.
final int numClusters = mPowerProfile.getNumCpuClusters();
- if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length !=
+ if (u.mCpuClusterSpeedTimesUs == null || u.mCpuClusterSpeedTimesUs.length !=
numClusters) {
- u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
+ u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
}
- for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) {
- final int speedsInCluster = clusterSpeeds[cluster].length;
- if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster !=
- u.mCpuClusterSpeed[cluster].length) {
- u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[speedsInCluster];
+ for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) {
+ final int speedsInCluster = clusterSpeedTimesMs[cluster].length;
+ if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster !=
+ u.mCpuClusterSpeedTimesUs[cluster].length) {
+ u.mCpuClusterSpeedTimesUs[cluster]
+ = new LongSamplingCounter[speedsInCluster];
}
- final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster];
+ final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster];
for (int speed = 0; speed < speedsInCluster; speed++) {
if (cpuSpeeds[speed] == null) {
cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
}
- cpuSpeeds[speed].addCountLocked(appCpuTimeMs * clusterSpeeds[cluster][speed]
- / totalCpuClustersTime);
+ cpuSpeeds[speed].addCountLocked(appCpuTimeUs
+ * clusterSpeedTimesMs[cluster][speed]
+ / totalCpuClustersTimeMs);
}
}
}
@@ -11747,7 +11756,7 @@
throw new ParcelFormatException("Incompatible cpu cluster arrangement");
}
- u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
+ u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
for (int cluster = 0; cluster < numClusters; cluster++) {
if (in.readInt() != 0) {
final int NSB = in.readInt();
@@ -11757,20 +11766,20 @@
NSB);
}
- u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB];
+ u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB];
for (int speed = 0; speed < NSB; speed++) {
if (in.readInt() != 0) {
- u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter(
+ u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter(
mOnBatteryTimeBase);
- u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in);
+ u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in);
}
}
} else {
- u.mCpuClusterSpeed[cluster] = null;
+ u.mCpuClusterSpeedTimesUs[cluster] = null;
}
}
} else {
- u.mCpuClusterSpeed = null;
+ u.mCpuClusterSpeedTimesUs = null;
}
u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
@@ -11862,7 +11871,7 @@
p.mWakeupAlarms.clear();
for (int iwa=0; iwa<NWA; iwa++) {
String tag = in.readString();
- Counter c = new Counter(mOnBatteryTimeBase);
+ Counter c = new Counter(mOnBatteryScreenOffTimeBase);
c.readSummaryFromParcelLocked(in);
p.mWakeupAlarms.put(tag, c);
}
@@ -12178,10 +12187,10 @@
u.mUserCpuTime.writeSummaryFromParcelLocked(out);
u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
- if (u.mCpuClusterSpeed != null) {
+ if (u.mCpuClusterSpeedTimesUs != null) {
out.writeInt(1);
- out.writeInt(u.mCpuClusterSpeed.length);
- for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) {
+ out.writeInt(u.mCpuClusterSpeedTimesUs.length);
+ for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) {
if (cpuSpeeds != null) {
out.writeInt(1);
out.writeInt(cpuSpeeds.length);
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
index 61c57c8..0df420b 100644
--- a/core/java/com/android/internal/os/ClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -19,6 +19,7 @@
import android.os.Trace;
import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;
/**
@@ -31,6 +32,7 @@
private ClassLoaderFactory() {}
private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
+ private static final String DEX_CLASS_LOADER_NAME = DexClassLoader.class.getName();
private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
DelegateLastClassLoader.class.getName();
@@ -44,12 +46,14 @@
}
/**
- * Returns true if {@code name} is the encoding for the PathClassLoader.
+ * Returns true if {@code name} is the encoding for either PathClassLoader or DexClassLoader.
+ * The two class loaders are grouped together because they have the same behaviour.
*/
public static boolean isPathClassLoaderName(String name) {
// For null values we default to PathClassLoader. This cover the case when packages
// don't specify any value for their class loaders.
- return name == null || PATH_CLASS_LOADER_NAME.equals(name);
+ return name == null || PATH_CLASS_LOADER_NAME.equals(name) ||
+ DEX_CLASS_LOADER_NAME.equals(name);
}
/**
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index 9d52e19..bb743c1 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -22,6 +22,7 @@
public class CpuPowerCalculator extends PowerCalculator {
private static final String TAG = "CpuPowerCalculator";
private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
+ private static final long MICROSEC_IN_HR = (long) 60 * 60 * 1000 * 1000;
private final PowerProfile mProfile;
public CpuPowerCalculator(PowerProfile profile) {
@@ -35,21 +36,22 @@
app.cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
final int numClusters = mProfile.getNumCpuClusters();
- double cpuPowerMaMs = 0;
+ double cpuPowerMaUs = 0;
for (int cluster = 0; cluster < numClusters; cluster++) {
final int speedsForCluster = mProfile.getNumSpeedStepsInCpuCluster(cluster);
for (int speed = 0; speed < speedsForCluster; speed++) {
- final double cpuSpeedStepPower = u.getTimeAtCpuSpeed(cluster, speed, statsType) *
+ final long timeUs = u.getTimeAtCpuSpeed(cluster, speed, statsType);
+ final double cpuSpeedStepPower = timeUs *
mProfile.getAveragePowerForCpu(cluster, speed);
if (DEBUG) {
Log.d(TAG, "UID " + u.getUid() + ": CPU cluster #" + cluster + " step #"
- + speed + " power="
- + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+ + speed + " timeUs=" + timeUs + " power="
+ + BatteryStatsHelper.makemAh(cpuSpeedStepPower / MICROSEC_IN_HR));
}
- cpuPowerMaMs += cpuSpeedStepPower;
+ cpuPowerMaUs += cpuSpeedStepPower;
}
}
- app.cpuPowerMah = cpuPowerMaMs / (60 * 60 * 1000);
+ app.cpuPowerMah = cpuPowerMaUs / MICROSEC_IN_HR;
if (DEBUG && (app.cpuTimeMs != 0 || app.cpuPowerMah != 0)) {
Log.d(TAG, "UID " + u.getUid() + ": CPU time=" + app.cpuTimeMs + " ms power="
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
index 9c7debb..757a112 100644
--- a/core/java/com/android/internal/os/KernelCpuSpeedReader.java
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -39,8 +39,8 @@
private static final String TAG = "KernelCpuSpeedReader";
private final String mProcFile;
- private final long[] mLastSpeedTimes;
- private final long[] mDeltaSpeedTimes;
+ private final long[] mLastSpeedTimesMs;
+ private final long[] mDeltaSpeedTimesMs;
// How long a CPU jiffy is in milliseconds.
private final long mJiffyMillis;
@@ -51,8 +51,8 @@
public KernelCpuSpeedReader(int cpuNumber, int numSpeedSteps) {
mProcFile = String.format("/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state",
cpuNumber);
- mLastSpeedTimes = new long[numSpeedSteps];
- mDeltaSpeedTimes = new long[numSpeedSteps];
+ mLastSpeedTimesMs = new long[numSpeedSteps];
+ mDeltaSpeedTimesMs = new long[numSpeedSteps];
long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
mJiffyMillis = 1000/jiffyHz;
}
@@ -68,27 +68,27 @@
TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
String line;
int speedIndex = 0;
- while (speedIndex < mLastSpeedTimes.length && (line = reader.readLine()) != null) {
+ while (speedIndex < mLastSpeedTimesMs.length && (line = reader.readLine()) != null) {
splitter.setString(line);
- Long.parseLong(splitter.next());
+ splitter.next();
long time = Long.parseLong(splitter.next()) * mJiffyMillis;
- if (time < mLastSpeedTimes[speedIndex]) {
+ if (time < mLastSpeedTimesMs[speedIndex]) {
// The stats reset when the cpu hotplugged. That means that the time
// we read is offset from 0, so the time is the delta.
- mDeltaSpeedTimes[speedIndex] = time;
+ mDeltaSpeedTimesMs[speedIndex] = time;
} else {
- mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
+ mDeltaSpeedTimesMs[speedIndex] = time - mLastSpeedTimesMs[speedIndex];
}
- mLastSpeedTimes[speedIndex] = time;
+ mLastSpeedTimesMs[speedIndex] = time;
speedIndex++;
}
} catch (IOException e) {
Slog.e(TAG, "Failed to read cpu-freq: " + e.getMessage());
- Arrays.fill(mDeltaSpeedTimes, 0);
+ Arrays.fill(mDeltaSpeedTimesMs, 0);
} finally {
StrictMode.setThreadPolicy(policy);
}
- return mDeltaSpeedTimes;
+ return mDeltaSpeedTimesMs;
}
}
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index 7295380..c89f546 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -134,9 +134,9 @@
.append(uid).append("\n");
sb.append("data=").append("(").append(uidTimeMs[i]).append(",")
.append(totalTimeMs).append(")").append("\n");
- sb.append("times=").append("(")
- .append(TimeUtils.formatForLogging(mLastTimeReadMs)).append(",")
- .append(TimeUtils.formatForLogging(mNowTimeMs)).append(")");
+ sb.append("times=").append("(");
+ TimeUtils.formatDuration(mLastTimeReadMs, sb); sb.append(",");
+ TimeUtils.formatDuration(mNowTimeMs, sb); sb.append(")");
Slog.wtf(TAG, sb.toString());
return;
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 45a8654..f978b57 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -116,4 +116,6 @@
void remQsTile(in ComponentName tile);
void clickQsTile(in ComponentName tile);
void handleSystemKey(in int key);
+
+ void showShutdownUi(boolean isReboot, String reason);
}
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 6fbfff8..e760f25 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -402,7 +402,6 @@
// Initialize destination fields
mDstMessenger = dstMessenger;
- linkToDeathMonitor();
if (DBG) log("connected srcHandler to the dstMessenger X");
}
diff --git a/core/java/com/android/internal/util/CollectionUtils.java b/core/java/com/android/internal/util/CollectionUtils.java
index dbb6e93..f0b47de 100644
--- a/core/java/com/android/internal/util/CollectionUtils.java
+++ b/core/java/com/android/internal/util/CollectionUtils.java
@@ -34,7 +34,7 @@
import java.util.stream.Stream;
/**
- * Utility methods for dealing with (typically {@link Nullable}) {@link Collection}s
+ * Utility methods for dealing with (typically {@code Nullable}) {@link Collection}s
*
* Unless a method specifies otherwise, a null value for a collection is treated as an empty
* collection of that type.
diff --git a/core/java/com/android/internal/util/JournaledFile.java b/core/java/com/android/internal/util/JournaledFile.java
index 9f775d3..5372fc0 100644
--- a/core/java/com/android/internal/util/JournaledFile.java
+++ b/core/java/com/android/internal/util/JournaledFile.java
@@ -20,7 +20,7 @@
import java.io.IOException;
/**
- * @deprecated Use {@link com.android.internal.os.AtomicFile} instead. It would
+ * @deprecated Use {@code AtomicFile} instead. It would
* be nice to update all existing uses of this to switch to AtomicFile, but since
* their on-file semantics are slightly different that would run the risk of losing
* data if at the point of the platform upgrade to the new code it would need to
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 9462a06..0d15758 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -67,8 +67,7 @@
private static final String TAG = "LockPatternUtils";
private static final boolean DEBUG = false;
- private static final boolean FRP_CREDENTIAL_ENABLED =
- Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.frpcredential.enable", false);
+ private static final boolean FRP_CREDENTIAL_ENABLED = true;
/**
* The key to identify when the lock pattern enabled flag is being accessed for legacy reasons.
@@ -1212,6 +1211,11 @@
*/
public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
+ if (userId == USER_FRP) {
+ // For secure password storage (that is required for FRP), the underlying storage also
+ // enforces the deadline. Since we cannot store settings for the FRP user, don't.
+ return deadline;
+ }
setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId);
setLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, timeoutMs, userId);
return deadline;
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index 0cf3164..7abc76a 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -132,8 +132,6 @@
* <p>
* When writing a {@link LayoutManager} you almost always want to use layout positions whereas when
* writing an {@link Adapter}, you probably want to use adapter positions.
- *
- * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_layoutManager
*/
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {
@@ -9591,11 +9589,6 @@
/**
* Parse the xml attributes to get the most common properties used by layout managers.
*
- * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation
- * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_spanCount
- * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout
- * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd
- *
* @return an object containing the properties as specified in the attrs.
*/
public static Properties getProperties(Context context, AttributeSet attrs,
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 5375651..a96b5dd 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -35,7 +35,8 @@
import java.io.IOException;
/**
- * Backup agent for various system-managed data, currently just the system wallpaper
+ * Backup agent for various system-managed data. Wallpapers are now handled by a
+ * separate package, but we still process restores from legacy datasets here.
*/
public class SystemBackupAgent extends BackupAgentHelper {
private static final String TAG = "SystemBackupAgent";
@@ -61,16 +62,19 @@
// TODO: http://b/22388012
private static final String WALLPAPER_IMAGE_DIR =
Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
- private static final String WALLPAPER_IMAGE = WallpaperBackupHelper.WALLPAPER_IMAGE;
+ public static final String WALLPAPER_IMAGE =
+ new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
+ "wallpaper").getAbsolutePath();
// TODO: Will need to change if backing up non-primary user's wallpaper
// TODO: http://b/22388012
private static final String WALLPAPER_INFO_DIR =
Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
- private static final String WALLPAPER_INFO = WallpaperBackupHelper.WALLPAPER_INFO;
+ public static final String WALLPAPER_INFO =
+ new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
+ "wallpaper_info.xml").getAbsolutePath();
// Use old keys to keep legacy data compatibility and avoid writing two wallpapers
private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
- private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY;
private WallpaperBackupHelper mWallpaperHelper = null;
@@ -98,13 +102,11 @@
// Slot in a restore helper for the older wallpaper backup schema to support restore
// from devices still generating data in that format.
mWallpaperHelper = new WallpaperBackupHelper(this,
- new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO },
- new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} );
+ new String[] { WALLPAPER_IMAGE_KEY} );
addHelper(WALLPAPER_HELPER, mWallpaperHelper);
// On restore, we also support a long-ago wallpaper data schema "system_files"
addHelper("system_files", new WallpaperBackupHelper(this,
- new String[] { WALLPAPER_IMAGE },
new String[] { WALLPAPER_IMAGE_KEY} ));
addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
@@ -115,27 +117,12 @@
addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
- try {
- super.onRestore(data, appVersionCode, newState);
-
- IWallpaperManager wallpaper = (IWallpaperManager) ServiceManager.getService(
- Context.WALLPAPER_SERVICE);
- if (wallpaper != null) {
- try {
- wallpaper.settingsRestored();
- } catch (RemoteException re) {
- Slog.e(TAG, "Couldn't restore settings\n" + re);
- }
- }
- } catch (IOException ex) {
- // If there was a failure, delete everything for the wallpaper, this is too aggressive,
- // but this is hopefully a rare failure.
- Slog.d(TAG, "restore failed", ex);
- (new File(WALLPAPER_IMAGE)).delete();
- (new File(WALLPAPER_INFO)).delete();
- }
+ super.onRestore(data, appVersionCode, newState);
}
+ /**
+ * Support for 'adb restore' of legacy archives
+ */
@Override
public void onRestoreFile(ParcelFileDescriptor data, long size,
int type, String domain, String path, long mode, long mtime)
@@ -183,12 +170,4 @@
}
}
}
-
- @Override
- public void onRestoreFinished() {
- // helper will be null following 'adb restore' or other full-data operation
- if (mWallpaperHelper != null) {
- mWallpaperHelper.onRestoreFinished();
- }
- }
}
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 31e954b..c457ab0 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -233,8 +233,9 @@
for (;;) {
uint32_t seq;
InputEvent* inputEvent;
+ int32_t displayId;
status_t status = mInputConsumer.consume(&mInputEventFactory,
- consumeBatches, frameTime, &seq, &inputEvent);
+ consumeBatches, frameTime, &seq, &inputEvent, &displayId);
if (status) {
if (status == WOULD_BLOCK) {
if (!skipCallbacks && !mBatchedInputEventPending
@@ -311,7 +312,8 @@
ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName());
}
env->CallVoidMethod(receiverObj.get(),
- gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
+ gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj,
+ displayId);
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching input event.");
skipCallbacks = true;
@@ -417,7 +419,7 @@
gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
gInputEventReceiverClassInfo.clazz,
- "dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
+ "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V");
gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 420ff2a..58ccef18 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -39,6 +39,8 @@
// Log debug messages about the dispatch cycle.
static const bool kDebugDispatchCycle = false;
+// Display id for default(primary) display.
+static const int32_t kDefaultDisplayId = 0;
static struct {
jclass clazz;
@@ -136,6 +138,7 @@
publishedSeq = mNextPublishedSeq++;
status_t status = mInputPublisher.publishMotionEvent(publishedSeq,
event->getDeviceId(), event->getSource(),
+ kDefaultDisplayId /* TODO(multi-display): propagate display id */,
event->getAction(), event->getActionButton(), event->getFlags(),
event->getEdgeFlags(), event->getMetaState(), event->getButtonState(),
event->getXOffset(), event->getYOffset(),
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d175422..208c776 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -305,7 +305,7 @@
<protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
<protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
<protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
- <protected-broadcast android:name="com.android.server.action.WIPE_EUICC_DATA" />
+ <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" />
<protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
<protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
<protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
@@ -545,6 +545,7 @@
<protected-broadcast android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
<protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
<protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
+ <protected-broadcast android:name="com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
@@ -2546,7 +2547,6 @@
<!-- Allows applications to get the installed and enabled print services.
@hide
@SystemApi
- @TestApi
<p>Protection level: signature|preinstalled
-->
<permission android:name="android.permission.READ_PRINT_SERVICES"
@@ -3169,6 +3169,10 @@
<permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi @hide Allows an application to manage carrier subscription plans. -->
+ <permission android:name="android.permission.MANAGE_SUBSCRIPTION_PLANS"
+ android:protectionLevel="signature|privileged" />
+
<!-- C2DM permission.
@hide Used internally.
-->
diff --git a/core/res/res/drawable-hdpi/ic_corp_icon.png b/core/res/res/drawable-hdpi/ic_corp_icon.png
deleted file mode 100644
index 06c5135..0000000
--- a/core/res/res/drawable-hdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_corp_icon.png b/core/res/res/drawable-mdpi/ic_corp_icon.png
deleted file mode 100644
index 79372b2..0000000
--- a/core/res/res/drawable-mdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_corp_icon.png b/core/res/res/drawable-xhdpi/ic_corp_icon.png
deleted file mode 100644
index 3626c7d..0000000
--- a/core/res/res/drawable-xhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxhdpi/ic_corp_icon.png
deleted file mode 100644
index d33319f..0000000
--- a/core/res/res/drawable-xxhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png b/core/res/res/drawable-xxxhdpi/ic_corp_icon.png
deleted file mode 100644
index 359e210..0000000
--- a/core/res/res/drawable-xxxhdpi/ic_corp_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml
new file mode 100644
index 0000000..78cce58
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_badge.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20.0"
+ android:viewportHeight="20.0">
+ <path
+ android:pathData="M10,10m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
+ android:fillColor="#FF6D00"/>
+ <path
+ android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/core/res/res/drawable/ic_corp_badge_case.xml b/core/res/res/drawable/ic_corp_badge_case.xml
index 0b6028c..2d11ee6 100644
--- a/core/res/res/drawable/ic_corp_badge_case.xml
+++ b/core/res/res/drawable/ic_corp_badge_case.xml
@@ -1,30 +1,9 @@
-<!--
-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.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20.0dp"
- android:height="20.0dp"
+ android:width="20dp"
+ android:height="20dp"
android:viewportWidth="20.0"
android:viewportHeight="20.0">
<path
- android:pathData="M15.2,6.2L4.8,6.2c-0.5,0.0 -0.9,0.4 -0.9,1.0L3.9,10.0c0.0,0.5 0.4,1.0 0.9,1.0l3.8,0.0l0.0,-1.0l2.9,0.0l0.0,1.0l3.8,0.0c0.5,0.0 1.0,-0.4 1.0,-1.0L16.3,7.1C16.2,6.6 15.8,6.2 15.2,6.2z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M8.6,12.9l0.0,-1.0L4.3,11.9l0.0,2.4c0.0,0.5 0.4,0.9 0.9,0.9l9.5,0.0c0.5,0.0 0.9,-0.4 0.9,-0.9l0.0,-2.4l-4.3,0.0l0.0,1.0L8.6,12.9z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M7.1,5.2l0.0,1.0 1.0,0.0 0.0,-1.0 3.799999,0.0 0.0,1.0 1.0,0.0 0.0,-1.0 -1.0,-0.9 -3.799999,0.0z"
+ android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z"
android:fillColor="#FFFFFF"/>
</vector>
diff --git a/core/res/res/drawable/ic_corp_badge_no_background.xml b/core/res/res/drawable/ic_corp_badge_no_background.xml
index 78322a9..8f7fb70 100644
--- a/core/res/res/drawable/ic_corp_badge_no_background.xml
+++ b/core/res/res/drawable/ic_corp_badge_no_background.xml
@@ -1,30 +1,9 @@
-<!--
-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.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:pathData="M20.801,5.981L17.13,5.98l0.001,-1.471l-2.053,-2.055L8.969,2.453L6.915,4.506L6.914,5.977L3.203,5.976c-1.216,0.0 -2.189,0.983 -2.189,2.199L1.0,12.406c0.0,1.216 0.983,2.2 2.199,2.2L10.0,14.608l0.0,-1.644l0.291,0.0l3.351,0.0l0.291,0.0l0.0,1.645l6.863,0.002c1.216,0.0 2.2,-0.983 2.2,-2.199L23.0,8.181C23.0,6.965 22.017,5.981 20.801,5.981zM15.076,5.979L8.968,5.978l0.001,-1.471l6.108,0.001L15.076,5.979z"
+ android:pathData="M20,6h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V8C22,6.89 21.11,6 20,6zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2s2,0.9 2,2S13.1,15 12,15zM14,6h-4V4h4V6z"
android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M13.911,16.646L9.978,16.646L9.978,15.48L1.673,15.48l0.0,4.105c0.0,1.216 0.959,2.2 2.175,2.2l16.13,0.004c1.216,0.0 2.203,-0.983 2.203,-2.199l0.0,-4.11l-8.27,0.0L13.910999,16.646z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M23.657,6.55 h4.72 v1.137 h-4.72z"
- android:fillColor="#00000000"/>
</vector>
diff --git a/core/res/res/drawable/ic_corp_badge_off.xml b/core/res/res/drawable/ic_corp_badge_off.xml
index 6799bf7..4774f31 100644
--- a/core/res/res/drawable/ic_corp_badge_off.xml
+++ b/core/res/res/drawable/ic_corp_badge_off.xml
@@ -1,56 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="20dp"
- android:viewportWidth="20"
- android:viewportHeight="20">
-
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20.0"
+ android:viewportHeight="20.0">
<path
- android:fillColor="#607D8B"
- android:pathData="M10,0 C15.5228,0,20,4.47715,20,10 C20,15.5228,15.5228,20,10,20
-C4.47715,20,0,15.5228,0,10 C0,4.47715,4.47715,0,10,0 Z" />
+ android:pathData="M10,10m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
+ android:fillColor="#607D8B"/>
<path
- android:pathData="M1.91667,1.91667 L18.0833,1.91667 L18.0833,18.0833 L1.91667,18.0833
-L1.91667,1.91667 Z" />
- <path
- android:fillColor="#ffffff"
- android:pathData="M11.9167,11.9167 L11.4167,11.9167 L11.4167,12.8333 L8.5,12.8333 L8.5,11.9167
-L4.16667,11.9167 L4.16667,14.3333 C4.16667,14.8333,4.58333,15.25,5.08333,15.25
-L14.75,15.25 C14.9167,15.25,15,15.25,15.1667,15.1667 L11.9167,11.9167 Z" />
- <path
- android:fillColor="#ffffff"
- android:pathData="M15.8333,13.75 L15.8333,11.9167 L14,11.9167
-C14.6667,12.6667,15.3333,13.3333,15.8333,13.75 Z" />
- <path
- android:fillColor="#ffffff"
- android:pathData="M6.16667,6.16667 L4.66667,6.16667 C4.16667,6.16667,3.75,6.58333,3.75,7.08333
-L3.75,10 C3.75,10.5,4.16667,10.9167,4.66667,10.9167 L8.5,10.9167 L8.5,10 L10,10
-L6.16667,6.16667 Z" />
- <path
- android:fillColor="#ffffff"
- android:pathData="M8.08333,6 L8.08333,5.16667 L11.9167,5.16667 L11.9167,6.08333 L8.16667,6.08333
-C9.66667,7.58333,11.4167,9.33333,12.9167,10.8333 L15.25,10.8333
-C15.75,10.8333,16.1667,10.4167,16.1667,9.91667 L16.1667,7.08333
-C16.1667,6.58333,15.75,6.16667,15.25,6.16667 L12.8333,6.16667 L12.8333,5.25
-L11.9167,4.33333 L8.08333,4.33333 L7.16667,5.16667
-C7.41667,5.41667,7.75,5.75,8.08333,6 Z" />
- <path
- android:fillColor="#ffffff"
- android:pathData="M15.6824,15.676 L14.6807,16.6777 L3.24921,5.24624 L4.25093,4.24452
-L15.6824,15.676 Z" />
-</vector>
\ No newline at end of file
+ android:pathData="M16.42,15.68l-0.85,-0.85L7.21,6.47L4.9,4.16L4.16,4.9l1.57,1.57H5.36c-0.65,0 -1.16,0.52 -1.16,1.17L4.2,14.05c0,0.65 0.52,1.17 1.17,1.17h9.12l1.2,1.2L16.42,15.68zM15.83,7.64c0.03,-0.65 -0.49,-1.17 -1.14,-1.14h-2.33V5.3c0,-0.65 -0.52,-1.17 -1.17,-1.14H8.86C8.22,4.14 7.7,4.66 7.7,5.3v0.19l8.14,8.17V7.64zM11.2,6.5H8.83V5.3h2.36V6.5z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/core/res/res/drawable/ic_corp_icon.xml b/core/res/res/drawable/ic_corp_icon.xml
new file mode 100644
index 0000000..a6b68f1
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_icon.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:pathData="M24,24m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"
+ android:fillColor="#FF6D00"/>
+ <path
+ android:pathData="M35.2,15.6h-5.6v-2.8c0,-1.55 -1.25,-2.8 -2.8,-2.8h-5.6c-1.55,0 -2.8,1.25 -2.8,2.8v2.8h-5.6c-1.55,0 -2.79,1.25 -2.79,2.8L10,33.8c0,1.55 1.25,2.8 2.8,2.8h22.4c1.55,0 2.8,-1.25 2.8,-2.8V18.4C38,16.85 36.75,15.6 35.2,15.6zM24,28.2c-1.54,0 -2.8,-1.26 -2.8,-2.8s1.26,-2.8 2.8,-2.8c1.54,0 2.8,1.26 2.8,2.8S25.54,28.2 24,28.2zM26.8,15.6h-5.6v-2.8h5.6V15.6z"
+ android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_icon_badge_case.xml b/core/res/res/drawable/ic_corp_icon_badge_case.xml
index d62eda4..dd653c6 100644
--- a/core/res/res/drawable/ic_corp_icon_badge_case.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge_case.xml
@@ -1,30 +1,9 @@
-<!--
-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.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64.0dp"
- android:height="64.0dp"
+ android:width="64dp"
+ android:height="64dp"
android:viewportWidth="64.0"
android:viewportHeight="64.0">
<path
- android:pathData="M56.4,43.5L41.8,43.5c-0.7,0.0 -1.3,0.6 -1.3,1.3l0.0,4.0c0.0,0.7 0.6,1.3 1.3,1.3L47.0,50.1l0.0,-1.3l4.0,0.0l0.0,1.4l5.4,0.0c0.7,0.0 1.3,-0.6 1.3,-1.3l0.0,-4.0C57.6,44.1 57.0,43.5 56.4,43.5z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M47.1,52.8l0.0,-1.3l-6.0,0.0l0.0,3.3c0.0,0.7 0.6,1.3 1.3,1.3l13.2,0.0c0.7,0.0 1.3,-0.6 1.3,-1.3l0.0,-3.3l-6.0,0.0l0.0,1.3L47.1,52.8z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M45.1,42.2l0.0,1.299999 1.300003,0.0 0.0,-1.299999 5.299999,0.0 0.0,1.299999 1.399998,0.0 0.0,-1.299999 -1.399998,-1.299999 -5.299999,0.0z"
+ android:pathData="M55.67,44h-3.33v-1.67c0,-0.92 -0.74,-1.67 -1.67,-1.67h-3.33c-0.92,0 -1.67,0.74 -1.67,1.67V44h-3.33c-0.92,0 -1.66,0.74 -1.66,1.67l-0.01,9.17c0,0.93 0.74,1.67 1.67,1.67h13.33c0.92,0 1.67,-0.74 1.67,-1.67v-9.17C57.33,44.74 56.59,44 55.67,44zM49,51.5c-0.92,0 -1.67,-0.75 -1.67,-1.67c0,-0.92 0.75,-1.67 1.67,-1.67s1.67,0.75 1.67,1.67C50.67,50.75 49.92,51.5 49,51.5zM50.67,44h-3.33v-1.67h3.33V44z"
android:fillColor="#FFFFFF"/>
</vector>
diff --git a/core/res/res/drawable/ic_corp_statusbar_icon.xml b/core/res/res/drawable/ic_corp_statusbar_icon.xml
index e742c0b..8f7fb70 100644
--- a/core/res/res/drawable/ic_corp_statusbar_icon.xml
+++ b/core/res/res/drawable/ic_corp_statusbar_icon.xml
@@ -1,30 +1,9 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:pathData="M20.801,5.981L17.13,5.98l0.001,-1.471l-2.053,-2.055L8.969,2.453L6.915,4.506L6.914,5.977L3.203,5.976c-1.216,0.0 -2.189,0.983 -2.189,2.199L1.0,12.406c0.0,1.216 0.983,2.2 2.199,2.2L10.0,14.608l0.0,-1.644l0.291,0.0l3.351,0.0l0.291,0.0l0.0,1.645l6.863,0.002c1.216,0.0 2.2,-0.983 2.2,-2.199L23.0,8.181C23.0,6.965 22.017,5.981 20.801,5.981zM15.076,5.979L8.968,5.978l0.001,-1.471l6.108,0.001L15.076,5.979z"
+ android:pathData="M20,6h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V8C22,6.89 21.11,6 20,6zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2s2,0.9 2,2S13.1,15 12,15zM14,6h-4V4h4V6z"
android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M13.911,16.646L9.978,16.646L9.978,15.48L1.673,15.48l0.0,4.105c0.0,1.216 0.959,2.2 2.175,2.2l16.13,0.004c1.216,0.0 2.203,-0.983 2.203,-2.199l0.0,-4.11l-8.27,0.0L13.910999,16.646z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M23.657,6.55 h4.72 v1.137 h-4.72z"
- android:fillColor="#00000000"/>
</vector>
diff --git a/core/res/res/drawable/ic_corp_user_badge.xml b/core/res/res/drawable/ic_corp_user_badge.xml
index 23809d5..6a0d902 100644
--- a/core/res/res/drawable/ic_corp_user_badge.xml
+++ b/core/res/res/drawable/ic_corp_user_badge.xml
@@ -1,24 +1,15 @@
-<!--
-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.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="36dp"
android:height="36dp"
android:viewportWidth="36.0"
android:viewportHeight="36.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M18,0C8.06,-0 0,8.06 0,18C0,27.94 8.06,36 18,36C27.94,36 36,27.94 36,18C36,8.06 27.94,0 18,0zM15.5,10.5L20.5,10.5L21.75,11.75L21.75,13L24.66,13C25.57,13 26.34,13.74 26.34,14.66L26.34,18C26.34,18.92 25.57,19.66 24.66,19.66L19.66,19.66L19.66,18.41L16.34,18.41L16.34,19.66L11.34,19.66C10.43,19.66 9.66,18.92 9.66,18L9.66,14.66C9.66,13.74 10.43,13 11.34,13L14.25,13L14.25,11.78L15.5,10.5zM15.5,11.75L15.5,13L20.5,13L20.5,11.75L15.5,11.75zM10.5,20.5L16.34,20.5L16.34,21.75L19.66,21.75L19.66,20.5L25.5,20.5L25.5,23.84C25.5,24.76 24.76,25.5 23.84,25.5L12.16,25.5C11.24,25.5 10.5,24.76 10.5,23.84L10.5,20.5z"/>
+ android:pathData="M16.3,11.3h3.4v1.7h-3.4z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M18,17.17c-0.92,0 -1.67,0.75 -1.67,1.67c0,0.92 0.75,1.67 1.67,1.67c0.92,0 1.67,-0.75 1.67,-1.67C19.67,17.92 18.92,17.17 18,17.17z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M18,0C8.06,0 0,8.06 0,18s8.06,18 18,18s18,-8.06 18,-18S27.94,0 18,0zM26.3,23.83c0,0.92 -0.71,1.67 -1.63,1.67H11.33c-0.93,0 -1.67,-0.74 -1.67,-1.67l0.01,-9.17c0,-0.92 0.73,-1.67 1.66,-1.67h3.37v-1.67c0,-0.93 0.71,-1.63 1.63,-1.63h3.33c0.93,0 1.63,0.71 1.63,1.63V13h3.37c0.93,0 1.63,0.74 1.63,1.67V23.83z"
+ android:fillColor="#FFFFFF"/>
</vector>
diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml
index 053b4f4..d57bd6a 100644
--- a/core/res/res/drawable/toast_frame.xml
+++ b/core/res/res/drawable/toast_frame.xml
@@ -17,8 +17,8 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <!-- background is material_grey_300 with .9 alpha -->
- <solid android:color="#E6E0E0E0" />
+ <!-- background is material_grey_200 with .9 alpha -->
+ <solid android:color="#E6EEEEEE" />
<corners android:radius="22dp" />
</shape>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index 2c08bf7..db586ec 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -34,8 +34,6 @@
android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.Toast"
android:textColor="@color/primary_text_default_material_light"
- android:shadowColor="#BB000000"
- android:shadowRadius="2.75"
/>
</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 39d6bfd2..c008194 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Word tydelik nie deur die selnetwerk by jou ligging aangebied nie"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk nie bereik nie"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Om opvangs te verbeter, probeer die soort verander wat by Instellings > Netwerk en internet > Mobiele netwerke > Voorkeurnetwerksoort gekies is."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi-oproepe is aktief"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Noodoproepe vereis \'n mobiele netwerk."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Opletberigte"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Oproepaanstuur"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Noodterugbel-modus"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Opletberigte oor mobiele data"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status van mobiele data"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-boodskappe"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Stemboodskappe"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-oproepe"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra eers jou diensverskaffer om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan. (Foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registreer by jou diensverskaffer"</item>
+ <item msgid="7472393097168811593">"Registreer by jou diensverskaffer (foutkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Stembystand"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nuwe kennisgewing"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuele sleutelbord"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fisieke sleutelbord"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sekuriteit"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB vir MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Gekoppel aan \'n USB-toebehoorsel"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tik vir meer opsies."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Oudiobykomstigheid word nie gesteun nie"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tik vir meer inligting"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoë oudiobykomstigheid bespeur"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Die aangehegde toestel is nie met hierdie foon versoenbaar nie. Tik om meer te wete te kom."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-ontfouting te deaktiveer."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c3e054e..c7073f0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"ለጊዜው በአካባቢዎ ባለው የተንቀሳቃሽ ስልክ አውታረ መረብ አይቀርብም"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"አውታረ መረብ ላይ መድረስ አይቻልም"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ቅበላን ለማሻሻል የተመረጠውን ዓይነት በቅንብሮች > አውታረ መረብ እና በይነመረብ > የተንቀሳቃሽ ስልክ አውታረ መረቦች > ተመራጭ የአውታረ መረብ ዓይነት ላይ ለመለወጥ ይሞክሩ።"</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"የWi‑Fi ጥሪ ገቢር ነው"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"የአደጋ ጥሪዎች የተንቀሳቃሽ ስልክ አውታረ መረብ ያስፈልጋቸዋል።"</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ማንቂያዎች"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ጥሪ ማስተላለፍ"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"የአደጋ ጊዜ ጥሪ ሁነታ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"የተንቀሳቃሽ ስልክ ውሂብ ማንቂያዎች"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"የተንቀሳቃሽ ስልክ ውሂብ ሁኔታ"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"የኤስኤምኤስ መልዕክቶች"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"የድምጽ መልዕክቶች"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"የWi-Fi ጥሪ"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ። (የስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
+ <item msgid="7472393097168811593">"ከእርስዎ አገልግሎት አቅራቢ ጋር ይመዝገቡ (ስህተት ኮድ፦ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"አዲስ ማሳወቂያ"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ምናባዊ የቁልፍ ሰሌዳ"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"አካላዊ ቁልፍ ሰሌዳ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ደህንነት"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"ዩኤስቢ ለMIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ለUSB ተቀጥላ ተያይዟል"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"የኦዲዮ መለዋወጫ አይደገፍም"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ተጨማሪ መረጃ ለማግኘት መታ ያድርጉ"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"የአናሎግ ኦዲዮ ረዳት እንዳለ ተደርሶበታል"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ዓባሪ የተያያዘው መሣሪያ ከዚህ ስልክ ጋር ተኳዃኝ አይደለም። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"የዩኤስቢ ማረሚያን ለማሰናከል መታ ያድርጉ።"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 0363078..01ba0f1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -84,10 +84,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"مؤقتا لا تقدمها شبكة الجوال في موقعك"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"يتعذر الوصول إلى الشبكة"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"لتحسين الاستقبال، يمكنك محاولة تغيير النوع المحدّد من خلال الإعدادات > الشبكة والإنترنت > شبكات الجوّال > نوع الشبكة المفضّل."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"الاتصال عبر Wi-Fi نشط"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"تتطلب مكالمات الطوارئ شبكة جوّال."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"التنبيهات"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"إعادة توجيه المكالمة"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"وضع معاودة الاتصال بالطوارئ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"تنبيهات بيانات الجوّال"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"حالة بيانات الجوّال"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"الرسائل القصيرة SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"رسائل البريد الصوتي"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"الاتصال عبر Wi-Fi"</string>
@@ -122,7 +124,7 @@
<item msgid="3910386316304772394">"لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات. (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+ <item msgid="7472393097168811593">"التسجيل لدى مشغِّل شبكة الجوّال (رمز الخطأ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -242,8 +244,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"المساعد الصوتي"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"إشعار جديد"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"لوحة المفاتيح الافتراضية"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"لوحة المفاتيح الفعلية"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"الأمان"</string>
@@ -1264,8 +1265,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB لـ MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"الاتصال بجهاز USB ملحق"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"انقر للحصول على المزيد من الخيارات."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ملحق الصوت غير متوافق"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"انقر للحصول على مزيد من المعلومات"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"تم اكتشاف ملحق صوتي تناظري"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"انقر لتعطيل تصحيح أخطاء USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"اختيار تعطيل تصحيح أخطاء USB."</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 1ef8e8b..500201b 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Müvəqqəti olaraq məkanda mobil şəbəkə tərəfindən təklif edilmir"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Şəbəkəyə daxil olmaq mümkün deyil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Qəbulu inkişaf etdirmək üçün seçilmiş növü Ayarlar > Şəbəkə və İnternet > Mobil şəbəkə > Tərcih edilən şəbəkə növü bölməsində dəyişə bilərsiniz."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi zəngi aktivdir"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Təcili zənglər üçün mobil şəbəkə tələb olunur."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Siqnallar"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Zəng yönləndirmə"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Təcili geriyə zəng rejimi"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobil data siqnalları"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Mobil data statusu"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS mesajları"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Səsli e-poçt mesajları"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi zəngi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Zəng etmək və Wi-Fi üzərindən mesaj göndərmək üçün əvvəlcə operatordan bu cihazı quraşdırmağı tələb edin. Sonra Ayarlardan Wi-Fi zəngini deaktiv edin. (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Operatorla qeydiyyatdan keçin"</item>
+ <item msgid="7472393097168811593">"Operator ilə qeydiyyatdan keçin (Xəta kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Səs Yardımçısı"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"İndi kilidləyin"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Yeni bildiriş"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual klaviatura"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziki klaviatura"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Təhlükəsizlik"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI üçün USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuara qoşuldu"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Əlavə seçimlər üçün tıklayın."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio aksesuar dəstəklənmir"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Daha çox məlumat üçün klikləyin"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoq audio aksesuar aşkarlandı"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Əlavə edilən cihaz bu telefonla uyğun deyil. Ətraflı məlumat üçün klikləyin."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB debaqı deaktivasiya etmək üçün tıklayın."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0b9e8dc..2226a23 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -81,10 +81,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Privremeno je onemogućeno na mobilnoj mreži na vašoj lokaciji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezivanje sa mrežom nije uspelo"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Podešavanja > Mreža i internet > Mobilne mreže > Željeni tip mreže."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Obaveštenja"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim za hitan povratni poziv"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Obaveštenja za mobilne podatke"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-ovi"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Pozivanje preko Wi-Fi mreže"</string>
@@ -119,7 +124,7 @@
<item msgid="3910386316304772394">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja. (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrujte se kod mobilnog operatera"</item>
+ <item msgid="7472393097168811593">"Registrujte se kod mobilnog operatera (kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj odmah"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Novo obaveštenje"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelna tastatura"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizička tastatura"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Bezbednost"</string>
@@ -1198,8 +1202,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Povezano sa USB dodatkom"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za još opcija."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Dodatna oprema za audio sadržaj nije podržana"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Otkrivena je analogna dodatna oprema za audio sadržaj"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključeni uređaj nije kompatibilan sa ovim telefonom. Dodirnite da biste saznali više."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je omogućeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index beca6e4..50607c8 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Часова не прапаноўваецца сеткай мабільнай сувязі ў вашым месцазанходжанні"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Немагчыма падключыцца да сеткі"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Налады > Сетка і інтэрнэт > Мабільныя сеткі > Прыярытэтны тып сеткі\"."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Абвесткі"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Пераадрасацыя выкліку"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Рэжым экстраннага зваротнага выкліку"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Абвесткі пра мабільныя даныя"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-паведамленні"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Паведамленні галасавой пошты"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-тэлефанія"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады. (Код памылкі: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Зарэгіструйцеся ў свайго аператара"</item>
+ <item msgid="7472393097168811593">"Зарэгіструйцеся ў свайго аператара (Код памылкі: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Галас. дапамога"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Заблакір. зараз"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Новае апавяшчэнне"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Віртуальная клавіятура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Фізічная клавіятура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Бяспека"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Падключаны да USB-прылады"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Дакраніцеся, каб атрымаць іншыя параметры."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аксесуар аўдыя не падтрымліваецца"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Націсніце, каб атрымаць дадатковую інфармацыю"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Выяўлены аксесуар аналагавага аўдыя"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Далучаная прылада не сумяшчальная з гэтым тэлефонам. Націсніце, каб даведацца больш."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Дакраніцеся, каб адключыць адладку па USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 82a474f..00ae087 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Временно не се предлага от мобилната мрежа в местоположението ви"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се установи връзка с мрежата"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"За да подобрите сигнала, променете избрания тип мрежа от „Настройки“ > „Мрежа и интернет“ > „Мобилни мрежи“ > „Предпочитан тип мрежа“."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Сигнали"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Пренасочване на обаждания"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим на обратно обаждане при спешност"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Сигнали за мобилните данни"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS съобщения"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Съобщения в гласовата поща"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Обаждания през Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките. (Код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Регистриране с оператора ви"</item>
+ <item msgid="7472393097168811593">"Регистриране с оператора ви (код на грешката: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Заключване сега"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известие"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуална клавиатура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физическа клавиатура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Сигурност"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Установена е връзка с аксесоар за USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Докоснете за още опции."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоаксесоарът не се поддържа"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Докоснете за още информация"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Открит е аналогов аудиоаксесоар"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Свързаното устройство не е съвместимо с този телефон. Докоснете, за да научите повече."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 86f0315..c019c6a 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"সাময়িকভাবে মোবাইল নেটওয়ার্ক আপনার অবস্থানে এই পরিষেবা দিচ্ছে না"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"নেটওয়ার্কের সিগন্যাল নেই"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"রিসেপশন উন্নত করতে সেটিংস > নেটওয়ার্ক এবং ইন্টারনেট > মোবাইল নেটওয়ার্ক > পছন্দের নেটওয়ার্কের ধরণ এ গিয়ে নির্বাচিত নেটওয়ার্কের ধরণ পরিবর্তন করে দেখুন।"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"সতর্কবার্তা"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"কল ফরওয়ার্ড করা"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"জরুরি কলব্যাক মোড"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"মোবাইল ডেটার সতর্কবার্তা"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"এসএমএস বার্তা"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ভয়েসমেল বার্তা"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"ওয়াই-ফাই কলিং"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"ওয়াই-ফাই এর মাধ্যমে কল করতে ও মেসেজ পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট-আপ করতে বলুন। তারপর আবার সেটিংস থেকে ওয়াই-ফাই কলিং চালু করুন। (ত্রুটি কোড: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
+ <item msgid="7472393097168811593">"আপনার পরিষেবা প্রদানকারীর সাথে রেজিস্টার করুন (ত্রুটি কোড: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"এখনই লক করুন"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"নতুন বিজ্ঞপ্তি"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ভার্চুয়াল কীবোর্ড"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ফিজিক্যাল কীবোর্ড"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"নিরাপত্তা"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI এর জন্য USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"একটি USB যন্ত্রাংশতে সংযুক্ত হয়েছে"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"আরো বিকল্পের জন্য আলতো চাপুন৷"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"অডিও অ্যাক্সেসরি সমর্থিত নয়"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"অ্যানালগ অডিও অ্যাক্সেসরি শনাক্ত করা হয়েছে"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"সংযুক্ত ডিভাইসটি এই ফোনের সাথে ব্যবহার করা যাবে না। আরও জানতে ট্যাপ করুন।"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ডিবাগিং অক্ষম করতে আলতো চাপুন৷"</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ত্রুটির প্রতিবেদন শেয়ার করা হচ্ছে..."</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 4a08928..cee6c34 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -81,10 +81,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Da poboljšate prijem, pokušajte promijeniti odabranu vrstu u meniju Postavke < Mreža i internet < Mobilne mreže < Preferirana vrsta mreže."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način rada za hitni povratni poziv"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozorenja za mobilne podatke"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS poruke"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi pozivanje"</string>
@@ -119,7 +124,7 @@
<item msgid="3910386316304772394">"Da biste pozivali i slali poruke koristeći Wi-Fi mrežu, prvo zatražite od operatera da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozivanje u Postavkama. (Kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrirajte se kod svog operatera"</item>
+ <item msgid="7472393097168811593">"Registrirajte se kod svog mobilnog operatera (Kȏd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj odmah"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Novo obavještenje"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelna tastatura"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizička tastatura"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sigurnost"</string>
@@ -1202,12 +1206,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Uspostavljena veza sa USB pohranom"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio pribor nije podržan"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Otkriven je analogni periferni uređaj"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da saznate više."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da onemogućite otklanjanje grešaka putem uređaja spojenog na USB."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string>
@@ -1424,7 +1427,7 @@
<string name="fingerprints" msgid="4516019619850763049">"Otisci prstiju:"</string>
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 otisak prsta:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 otisak prsta:"</string>
- <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Vidi sve"</string>
+ <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Prikaži sve"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Odaberite aktivnost"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Podijeliti sa"</string>
<string name="sending" msgid="3245653681008218030">"Slanje..."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index dd2616b..b6aea53 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"La xarxa mòbil de la teva ubicació temporalment no ofereix aquest servei"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No es pot accedir a la xarxa"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Per millorar la recepció, prova de canviar el tipus de xarxa a Configuració > Xarxa i Internet > Xarxes mòbils > Tipus de xarxa preferit."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Desviació de trucades"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de devolució de trucada d\'emergència"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertes de dades mòbils"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Missatges SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Missatges de veu"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Trucades per Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi a Configuració. (Codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registra\'t amb el teu operador de telefonia mòbil"</item>
+ <item msgid="7472393097168811593">"Registra\'t amb el teu operador de telefonia mòbil (codi d\'error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. per veu"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notificació nova"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclat virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclat físic"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Seguretat"</string>
@@ -874,8 +878,8 @@
<string name="years" msgid="6881577717993213522">"anys"</string>
<string name="now_string_shortest" msgid="8912796667087856402">"ara"</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item>
- <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per a MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connectat a un accessori USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toca per veure més opcions."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"L\'accessori d\'àudio no és compatible"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca per obtenir més informació"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"S\'ha detectat un accessori d\'àudio analògic"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositiu connectat no és compatible amb aquest telèfon. Toca per obtenir més informació."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca per desactivar la depuració USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració USB"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 4f053b4..6f4b6ad 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Mobilní síť ve vaší oblasti tuto službu dočasně nenabízí"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"K síti se nelze připojit"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Chcete-li zlepšit příjem, zkuste změnit vybraný typ sítě v Nastavení > Síť a internet > Mobilní sítě > Preferovaný typ sítě."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornění"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Přesměrování hovorů"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim tísňového zpětného volání"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozornění na mobilní data"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Zprávy SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Hlasové zprávy"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Volání přes Wi-Fi"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Chcete-li volat a odesílat SMS přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrace u operátora"</item>
+ <item msgid="7472393097168811593">"Zaregistrujte se u operátora (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Hlas. asistence"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nové oznámení"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuální klávesnice"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyzická klávesnice"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Zabezpečení"</string>
@@ -835,7 +839,7 @@
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"změna oprávnění prohlížeče poskytovat informace o zeměpisné poloze"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Umožňuje aplikaci upravit oprávnění funkce geolokace v prohlížeči. Škodlivé aplikace toho mohou využít k odeslání údajů o poloze na libovolné webové stránky."</string>
<string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
- <string name="save_password_notnow" msgid="6389675316706699758">"Nyní ne"</string>
+ <string name="save_password_notnow" msgid="6389675316706699758">"Teď ne"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamatovat"</string>
<string name="save_password_never" msgid="8274330296785855105">"Nikdy"</string>
<string name="open_permission_deny" msgid="7374036708316629800">"Nemáte povolení otevřít tuto stránku."</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB v režimu MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno k perifernímu zařízení USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte další možnosti."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvukové příslušenství není podporováno"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Klepnutím zobrazíte další informace"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Bylo zjištěno analogové zvukové příslušenství"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Připojené zařízení není s tímto telefonem kompatibilní. Klepnutím zobrazíte další informace."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladění USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 692a851..96dc1e7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbydes i øjeblikket ikke af mobilnetværket på din placering"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Der er ingen forbindelse til netværket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Hvis du vil forbedre signalet, kan du prøve at ændre den valgte netværkstype i Indstillinger > Netværk og internet > Mobilnetværk > Foretrukken netværkstype."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Underretninger"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Viderestilling af opkald"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Nødtilbagekaldstilstand"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Underretninger om mobildata"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Sms-beskeder"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Talebeskeder"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-opkald"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du aktivere Wi-Fi-opkald igen fra Indstillinger. (Fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrer dig hos dit mobilselskab"</item>
+ <item msgid="7472393097168811593">"Registrer dig hos dit mobilselskab (fejlkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Taleassistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ny underretning"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysisk tastatur"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sikkerhed"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB til MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tryk for at se flere muligheder."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret understøttes ikke"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryk for at få flere oplysninger"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Der blev registreret et analogt lydtilbehør"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den tilsluttede enhed er ikke kompatibel med denne telefon. Tryk for at få flere oplysninger."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tryk for at deaktivere fejlretning via USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1f5873c..2997eda 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Derzeit nicht im Mobilfunknetz in deiner Region verfügbar"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Netzwerk nicht erreichbar"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Der Empfang lässt sich möglicherweise verbessern, indem du unter \"Einstellungen\" > \"Netzwerk\" & \"Internet\" > \"Mobilfunknetze\" > \"Bevorzugter Netzwerktyp\" einen anderen Typ auswählst."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Warnmeldungen"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Anrufweiterleitung"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Notfallrückrufmodus"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Warnmeldungen für mobile Daten"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mailboxnachrichten"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Anrufe über WLAN"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen. (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registriere dich bei deinem Mobilfunkanbieter."</item>
+ <item msgid="7472393097168811593">"Registriere dich bei deinem Mobilfunkanbieter (Fehlercode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Neue Benachrichtigung"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Bildschirmtastatur"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physische Tastatur"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sicherheit"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB für MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Mit USB-Zubehör verbunden"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Für weitere Optionen tippen."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audiozubehör wird nicht unterstützt"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tippen, um weitere Informationen zu erhalten"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoges Audiozubehör erkannt"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Das angeschlossene Gerät ist nicht mit diesem Smartphone kompatibel. Für weitere Informationen tippen."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7ab10d2..3d372cc 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Δεν προσφέρεται προσωρινά από το δίκτυο κινητής τηλεφωνίας στην τοποθεσία σας"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Δεν είναι δυνατή η σύνδεση στο δίκτυο"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Για να βελτιώσετε τη λήψη, δοκιμάστε να αλλάξετε τον επιλεγμένο τύπο από τις Ρυθμίσεις > Δίκτυο και διαδίκτυο > Δίκτυα κινητής τηλεφωνίας > Προτιμώμενος τύπος δικτύου."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Ειδοποιήσεις"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Προώθηση κλήσης"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Λειτουργία επιστροφής κλήσης έκτακτης ανάγκης"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Ειδοποιήσεις δεδομένων κινητής τηλεφωνίας"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Μηνύματα SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Μηνύματα αυτόματου τηλεφωνητή"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Κλήση Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά την Κλήση Wi-Fi από τις Ρυθμίσεις. (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+ <item msgid="7472393097168811593">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας που χρησιμοποιείτε (Κωδικός σφάλματος: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Φων.υποβοηθ."</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Νέα ειδοποίηση"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Εικονικό πληκτρολόγιο"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Φυσικό πληκτρολόγιο"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Ασφάλεια"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB για MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Σύνδεση σε αξεσουάρ USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Πατήστε για περισσότερες επιλογές."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Το εξάρτημα ήχου δεν υποστηρίζεται"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Πατήστε για να δείτε περισσότερες πληροφορίες"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Εντοπίστηκε αναλογικό αξεσουάρ ήχου"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Η συνδεδεμένη συσκευή δεν είναι συμβατή με αυτό το τηλέφωνο. Πατήστε για να μάθετε περισσότερα."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Πατήστε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 213d966..2a3b058 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -80,10 +80,13 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings > Network & Internet > Mobile networks > Preferred network type."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi calling is active"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Emergency calls require a mobile network."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobile data alerts"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS messages"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi Calling"</string>
@@ -118,7 +121,7 @@
<item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Register with your operator"</item>
+ <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +233,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -1176,8 +1178,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 213d966..2a3b058 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -80,10 +80,13 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings > Network & Internet > Mobile networks > Preferred network type."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi calling is active"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Emergency calls require a mobile network."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobile data alerts"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS messages"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi Calling"</string>
@@ -118,7 +121,7 @@
<item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Register with your operator"</item>
+ <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +233,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -1176,8 +1178,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 213d966..2a3b058 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -80,10 +80,13 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings > Network & Internet > Mobile networks > Preferred network type."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi calling is active"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Emergency calls require a mobile network."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobile data alerts"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS messages"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi Calling"</string>
@@ -118,7 +121,7 @@
<item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Register with your operator"</item>
+ <item msgid="7472393097168811593">"Register with your operator (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +233,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
@@ -1176,8 +1178,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogue audio accessory detected"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
diff --git a/core/res/res/values-en-rXC-watch/strings.xml b/core/res/res/values-en-rXC-watch/strings.xml
new file mode 100644
index 0000000..0287c52
--- /dev/null
+++ b/core/res/res/values-en-rXC-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="android_upgrading_apk" msgid="1090732262010398759">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="permgrouplab_sensors" msgid="202675452368612754">"Sensors"</string>
+</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..914e539
--- /dev/null
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -0,0 +1,1770 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="byteShort" msgid="8340973892742019101">"B"</string>
+ <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+ <string name="untitled" msgid="4638956954852782576">"<Untitled>"</string>
+ <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
+ <string name="unknownName" msgid="6867811765370350269">"Unknown"</string>
+ <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
+ <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+ <string name="mmiError" msgid="5154499457739052907">"Connection problem or invalid MMI code."</string>
+ <string name="mmiFdnError" msgid="5224398216385316471">"Operation is restricted to fixed dialing numbers only."</string>
+ <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"Can not change call forwarding settings from your phone while you are roaming."</string>
+ <string name="serviceEnabled" msgid="8147278346414714315">"Service was enabled."</string>
+ <string name="serviceEnabledFor" msgid="6856228140453471041">"Service was enabled for:"</string>
+ <string name="serviceDisabled" msgid="1937553226592516411">"Service has been disabled."</string>
+ <string name="serviceRegistered" msgid="6275019082598102493">"Registration was successful."</string>
+ <string name="serviceErased" msgid="1288584695297200972">"Erasure was successful."</string>
+ <string name="passwordIncorrect" msgid="7612208839450128715">"Incorrect password."</string>
+ <string name="mmiComplete" msgid="8232527495411698359">"MMI complete."</string>
+ <string name="badPin" msgid="9015277645546710014">"The old PIN you typed isn\'t correct."</string>
+ <string name="badPuk" msgid="5487257647081132201">"The PUK you typed isn\'t correct."</string>
+ <string name="mismatchPin" msgid="609379054496863419">"The PINs you typed don\'t match."</string>
+ <string name="invalidPin" msgid="3850018445187475377">"Type a PIN that is 4 to 8 numbers."</string>
+ <string name="invalidPuk" msgid="8761456210898036513">"Type a PUK that is 8 numbers or longer."</string>
+ <string name="needPuk" msgid="919668385956251611">"Your SIM card is PUK-locked. Type the PUK code to unlock it."</string>
+ <string name="needPuk2" msgid="4526033371987193070">"Type PUK2 to unblock SIM card."</string>
+ <string name="enablePin" msgid="209412020907207950">"Unsuccessful, enable SIM/RUIM Lock."</string>
+ <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
+ <item quantity="other">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+ <item quantity="one">You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM is locked.</item>
+ </plurals>
+ <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+ <string name="meid" msgid="4841221237681254195">"MEID"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
+ <string name="ClirMmi" msgid="7784673673446833091">"Outgoing Caller ID"</string>
+ <string name="ColpMmi" msgid="3065121483740183974">"Connected Line ID"</string>
+ <string name="ColrMmi" msgid="4996540314421889589">"Connected Line ID Restriction"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Call forwarding"</string>
+ <string name="CwMmi" msgid="9129678056795016867">"Call waiting"</string>
+ <string name="BaMmi" msgid="455193067926770581">"Call barring"</string>
+ <string name="PwdMmi" msgid="7043715687905254199">"Password change"</string>
+ <string name="PinMmi" msgid="3113117780361190304">"PIN change"</string>
+ <string name="CnipMmi" msgid="3110534680557857162">"Calling number present"</string>
+ <string name="CnirMmi" msgid="3062102121430548731">"Calling number restricted"</string>
+ <string name="ThreeWCMmi" msgid="9051047170321190368">"Three way calling"</string>
+ <string name="RuacMmi" msgid="7827887459138308886">"Rejection of undesired annoying calls"</string>
+ <string name="CndMmi" msgid="3116446237081575808">"Calling number delivery"</string>
+ <string name="DndMmi" msgid="1265478932418334331">"Do not disturb"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Caller ID defaults to restricted. Next call: Restricted"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Caller ID defaults to restricted. Next call: Not restricted"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Caller ID defaults to not restricted. Next call: Restricted"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Caller ID defaults to not restricted. Next call: Not restricted"</string>
+ <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
+ <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"No data service"</string>
+ <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No emergency calling"</string>
+ <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"No voice service"</string>
+ <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
+ <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
+ <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t reach network"</string>
+ <string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"To improve reception, try changing the type selected at Settings > Network & Internet > Mobile networks > Preferred network type."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi calling is active"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Emergency calls require a mobile network."</string>
+ <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
+ <string name="notification_channel_call_forward" msgid="2419697808481833249">"Call forwarding"</string>
+ <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Mobile data status"</string>
+ <string name="notification_channel_sms" msgid="3441746047346135073">"SMS messages"</string>
+ <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string>
+ <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi calling"</string>
+ <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer requested TTY Mode FULL"</string>
+ <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer requested TTY Mode HCO"</string>
+ <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer requested TTY Mode VCO"</string>
+ <string name="peerTtyModeOff" msgid="3280819717850602205">"Peer requested TTY Mode OFF"</string>
+ <string name="serviceClassVoice" msgid="1258393812335258019">"Voice"</string>
+ <string name="serviceClassData" msgid="872456782077937893">"Data"</string>
+ <string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
+ <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+ <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+ <string name="serviceClassDataSync" msgid="7530000519646054776">"Sync"</string>
+ <string name="serviceClassPacket" msgid="6991006557993423453">"Packet"</string>
+ <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+ <string name="roamingText0" msgid="7170335472198694945">"Roaming Indicator On"</string>
+ <string name="roamingText1" msgid="5314861519752538922">"Roaming Indicator Off"</string>
+ <string name="roamingText2" msgid="8969929049081268115">"Roaming Indicator Flashing"</string>
+ <string name="roamingText3" msgid="5148255027043943317">"Out of Neighborhood"</string>
+ <string name="roamingText4" msgid="8808456682550796530">"Out of Building"</string>
+ <string name="roamingText5" msgid="7604063252850354350">"Roaming - Preferred System"</string>
+ <string name="roamingText6" msgid="2059440825782871513">"Roaming - Available System"</string>
+ <string name="roamingText7" msgid="7112078724097233605">"Roaming - Alliance Partner"</string>
+ <string name="roamingText8" msgid="5989569778604089291">"Roaming - Premium Partner"</string>
+ <string name="roamingText9" msgid="7969296811355152491">"Roaming - Full Service Functionality"</string>
+ <string name="roamingText10" msgid="3992906999815316417">"Roaming - Partial Service Functionality"</string>
+ <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner On"</string>
+ <string name="roamingText12" msgid="1189071119992726320">"Roaming Banner Off"</string>
+ <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
+ <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Calling"</string>
+ <string-array name="wfcOperatorErrorAlertMessages">
+ <item msgid="3910386316304772394">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ </string-array>
+ <string-array name="wfcOperatorErrorNotificationMessages">
+ <item msgid="7472393097168811593">"Register with your carrier (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ </string-array>
+ <string-array name="wfcSpnFormats">
+ <item msgid="6830082633573257149">"%s"</item>
+ <item msgid="4397097370387921767">"%s Wi-Fi Calling"</item>
+ </string-array>
+ <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
+ <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
+ <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
+ <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi only"</string>
+ <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+ <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+ <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> after <xliff:g id="TIME_DELAY">{2}</xliff:g> seconds"</string>
+ <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+ <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+ <string name="fcComplete" msgid="3118848230966886575">"Feature code complete."</string>
+ <string name="fcError" msgid="3327560126588500777">"Connection problem or invalid feature code."</string>
+ <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+ <string name="httpError" msgid="7956392511146698522">"There was a network error."</string>
+ <string name="httpErrorLookup" msgid="4711687456111963163">"Couldn\'t find the URL."</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"The site authentication scheme isn\'t supported."</string>
+ <string name="httpErrorAuth" msgid="1435065629438044534">"Couldn\'t authenticate."</string>
+ <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Authentication via the proxy server was unsuccessful."</string>
+ <string name="httpErrorConnect" msgid="8714273236364640549">"Couldn\'t connect to the server."</string>
+ <string name="httpErrorIO" msgid="2340558197489302188">"Couldn\'t communicate with the server. Try again later."</string>
+ <string name="httpErrorTimeout" msgid="4743403703762883954">"The connection to the server timed out."</string>
+ <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"The page contains too many server redirects."</string>
+ <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"The protocol isn\'t supported."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Couldn\'t establish a secure connection."</string>
+ <string name="httpErrorBadUrl" msgid="3636929722728881972">"Couldn\'t open the page because the URL is invalid."</string>
+ <string name="httpErrorFile" msgid="2170788515052558676">"Couldn\'t access the file."</string>
+ <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Couldn\'t find the requested file."</string>
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Too many requests are being processed. Try again later."</string>
+ <string name="notification_title" msgid="8967710025036163822">"Signin error for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+ <string name="contentServiceSync" msgid="8353523060269335667">"Sync"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sync"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Too many <xliff:g id="CONTENT_TYPE">%s</xliff:g> deletes."</string>
+ <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
+ <string name="low_memory" product="watch" msgid="4415914910770005166">"Watch storage is full. Delete some files to free space."</string>
+ <string name="low_memory" product="tv" msgid="516619861191025923">"TV storage is full. Delete some files to free space."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
+ <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
+ <item quantity="other">Certificate authorities installed</item>
+ <item quantity="one">Certificate authority installed</item>
+ </plurals>
+ <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"By an unknown third party"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"By your work profile admin"</string>
+ <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"By <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
+ <string name="work_profile_deleted" msgid="5005572078641980632">"Work profile deleted"</string>
+ <string name="work_profile_deleted_description" msgid="1100529432509639864">"Work profile deleted due to missing admin app"</string>
+ <string name="work_profile_deleted_details" msgid="6307630639269092360">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Your work profile is no longer available on this device"</string>
+ <string name="network_logging_notification_title" msgid="6399790108123704477">"Device is managed"</string>
+ <string name="network_logging_notification_text" msgid="7930089249949354026">"Your organization manages this device and may monitor network traffic. Tap for details."</string>
+ <string name="factory_reset_warning" msgid="5423253125642394387">"Your device will be erased"</string>
+ <string name="factory_reset_message" msgid="7972496262232832457">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organizations admin."</string>
+ <string name="me" msgid="6545696007631404292">"Me"</string>
+ <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
+ <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV options"</string>
+ <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
+ <string name="silent_mode" msgid="7167703389802618663">"Silent mode"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"Turn on wireless"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"Turn off wireless"</string>
+ <string name="screen_lock" msgid="799094655496098153">"Screen lock"</string>
+ <string name="power_off" msgid="4266614107412865048">"Power off"</string>
+ <string name="silent_mode_silent" msgid="319298163018473078">"Ringer off"</string>
+ <string name="silent_mode_vibrate" msgid="7072043388581551395">"Ringer vibrate"</string>
+ <string name="silent_mode_ring" msgid="8592241816194074353">"Ringer on"</string>
+ <string name="reboot_to_update_title" msgid="6212636802536823850">"Android system update"</string>
+ <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Preparing to update…"</string>
+ <string name="reboot_to_update_package" msgid="3871302324500927291">"Processing the update package…"</string>
+ <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Restarting…"</string>
+ <string name="reboot_to_reset_title" msgid="4142355915340627490">"Factory data reset"</string>
+ <string name="reboot_to_reset_message" msgid="2432077491101416345">"Restarting…"</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"Shutting down…"</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Your tablet will shut down."</string>
+ <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Your TV will shut down."</string>
+ <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Your watch will shut down."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Your phone will shut down."</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"Do you want to shut down?"</string>
+ <string name="reboot_safemode_title" msgid="7054509914500140361">"Reboot to safe mode"</string>
+ <string name="reboot_safemode_confirm" msgid="55293944502784668">"Do you want to reboot into safe mode? This will disable all third party applications you have installed. They will be restored when you reboot again."</string>
+ <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
+ <string name="no_recent_tasks" msgid="8794906658732193473">"No recent apps."</string>
+ <string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet options"</string>
+ <string name="global_actions" product="tv" msgid="7240386462508182976">"TV options"</string>
+ <string name="global_actions" product="default" msgid="2406416831541615258">"Phone options"</string>
+ <string name="global_action_lock" msgid="2844945191792119712">"Screen lock"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"Power off"</string>
+ <string name="global_action_emergency" msgid="7112311161137421166">"Emergency"</string>
+ <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
+ <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+ <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an e-mail message. It will take a little time from starting the bug report until it is ready to be sent; please be patient."</string>
+ <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
+ <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem, and take screenshots. It might omit some less-used sections that take a long time to report."</string>
+ <string name="bugreport_option_full_title" msgid="6354382025840076439">"Full report"</string>
+ <string name="bugreport_option_full_summary" msgid="7210859858969115745">"Use this option for minimal system interference when your device is unresponsive or too slow, or when you need all report sections. Does not allow you to enter more details or take additional screenshots."</string>
+ <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+ <item quantity="other">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
+ <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_0">%d</xliff:g> second.</item>
+ </plurals>
+ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
+ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Airplane mode"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Airplane mode is ON"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Airplane mode is OFF"</string>
+ <string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+ <string name="global_action_assist" msgid="3892832961594295030">"Assist"</string>
+ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
+ <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+ <string name="notification_hidden_text" msgid="6351207030447943784">"New notification"</string>
+ <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual keyboard"</string>
+ <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Physical keyboard"</string>
+ <string name="notification_channel_security" msgid="7345516133431326347">"Security"</string>
+ <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
+ <string name="notification_channel_account" msgid="7577959168463122027">"Account status"</string>
+ <string name="notification_channel_developer" msgid="7579606426860206060">"Developer messages"</string>
+ <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
+ <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
+ <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
+ <string name="notification_channel_network_available" msgid="4531717914138179517">"Network available"</string>
+ <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN status"</string>
+ <string name="notification_channel_device_admin" msgid="1568154104368069249">"Device administration"</string>
+ <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
+ <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
+ <string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
+ <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+ <string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
+ <string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string>
+ <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
+ <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
+ <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
+ <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"send and view SMS messages"</string>
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"access photos, media, and files on your device"</string>
+ <string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
+ <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
+ <string name="permgrouplab_phone" msgid="5229115638567440675">"Phone"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window you\'re interacting with."</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
+ <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Tapped items will be spoken aloud and the screen can be explored using gestures."</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observe text you type"</string>
+ <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
+ <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Control display magnification"</string>
+ <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
+ <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
+ <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch, and perform other gestures."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
+ <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
+ <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
+ <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
+ <string name="permdesc_statusBarService" msgid="716113660795976060">"Allows the app to be the status bar."</string>
+ <string name="permlab_expandStatusBar" msgid="1148198785937489264">"expand/collapse status bar"</string>
+ <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Allows the app to expand or collapse the status bar."</string>
+ <string name="permlab_install_shortcut" msgid="4279070216371564234">"install shortcuts"</string>
+ <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Allows an application to add Homescreen shortcuts without user intervention."</string>
+ <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uninstall shortcuts"</string>
+ <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Allows the application to remove Homescreen shortcuts without user intervention."</string>
+ <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"reroute outgoing calls"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Allows the app to see the number being dialed during an outgoing call with the option to redirect the call to a different number or abort the call altogether."</string>
+ <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"answer phone calls"</string>
+ <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"Allows the app to answer an incoming phone call."</string>
+ <string name="permlab_receiveSms" msgid="8673471768947895082">"receive text messages (SMS)"</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read cell broadcast messages"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read cell broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency cell broadcast is received."</string>
+ <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"send and view SMS messages"</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Allows the app to send SMS messages. This may result in unexpected charges. Malicious apps may cost you money by sending messages without your confirmation."</string>
+ <string name="permlab_readSms" msgid="8745086572213270480">"read your text messages (SMS or MMS)"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"This app can read all SMS (text) messages stored on your tablet."</string>
+ <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"This app can read all SMS (text) messages stored on your TV."</string>
+ <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"This app can read all SMS (text) messages stored on your phone."</string>
+ <string name="permlab_receiveWapPush" msgid="5991398711936590410">"receive text messages (WAP)"</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Allows the app to receive and process WAP messages. This permission includes the ability to monitor or delete messages sent to you without showing them to you."</string>
+ <string name="permlab_getTasks" msgid="6466095396623933906">"retrieve running apps"</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"Allows the app to retrieve information about currently and recently running tasks. This may allow the app to discover information about which applications are used on the device."</string>
+ <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"manage profile and device owners"</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Allows apps to set the profile owners and the device owner."</string>
+ <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorder running apps"</string>
+ <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Allows the app to move tasks to the foreground and background. The app may do this without your input."</string>
+ <string name="permlab_enableCarMode" msgid="5684504058192921098">"enable car mode"</string>
+ <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Allows the app to enable the car mode."</string>
+ <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"close other apps"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Allows the app to end background processes of other apps. This may cause other apps to stop running."</string>
+ <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"This app can appear on top of other apps"</string>
+ <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"This app can appear on top of other apps or other parts of the screen. This may interfere with normal app usage and change the way that other apps appear."</string>
+ <string name="permlab_runInBackground" msgid="7365290743781858803">"run in the background"</string>
+ <string name="permdesc_runInBackground" msgid="7370142232209999824">"This app can run in the background. This may drain battery faster."</string>
+ <string name="permlab_useDataInBackground" msgid="8694951340794341809">"use data in the background"</string>
+ <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"This app can use data in the background. This may increase data usage."</string>
+ <string name="permlab_persistentActivity" msgid="8841113627955563938">"make app always run"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the tablet."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the TV."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone."</string>
+ <string name="permlab_getPackageSize" msgid="7472921768357981986">"measure app storage space"</string>
+ <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Allows the app to retrieve its code, data, and cache sizes"</string>
+ <string name="permlab_writeSettings" msgid="2226195290955224730">"modify system settings"</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"Allows the app to modify the system\'s settings data. Malicious apps may corrupt your system\'s configuration."</string>
+ <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"run at startup"</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the tablet and allow the app to slow down the overall tablet by always running."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the TV and allow the app to slow down the overall tablet by always running."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the phone and allow the app to slow down the overall phone by always running."</string>
+ <string name="permlab_broadcastSticky" msgid="7919126372606881614">"send sticky broadcast"</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the tablet slow or unstable by causing it to use too much memory."</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the TV slow or unstable by causing it to use too much memory."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
+ <string name="permlab_readContacts" msgid="8348481131899886131">"read your contacts"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Allows the app to read data about your contacts stored on your TV, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permlab_writeContacts" msgid="5107492086416793544">"modify your contacts"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Allows the app to modify the data about your contacts stored on your TV, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"read call log"</string>
+ <string name="permdesc_readCallLog" msgid="3204122446463552146">"This app can read your call history."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"write call log"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+ <string name="permlab_bodySensors" msgid="4683341291818520277">"access body sensors (like heart rate monitors)"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string>
+ <string name="permlab_readCalendar" msgid="6716116972752441641">"Read calendar events and details"</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"This app can read all calendar events stored on your TV and share or save your calendar data."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"This app can read all calendar events stored on your phone and share or save your calendar data."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"add or modify calendar events and send email to guests without owners\' knowledge"</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"This app can add, remove, or change calendar events on your tablet. This app can send messages that may appear to come from calendar owners, or change events without notifying their owners."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"This app can add, remove, or change calendar events on your TV. This app can send messages that may appear to come from calendar owners, or change events without notifying their owners."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"This app can add, remove, or change calendar events on your phone. This app can send messages that may appear to come from calendar owners, or change events without notifying their owners."</string>
+ <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
+ <string name="permlab_accessFineLocation" msgid="251034415460950944">"access precise location (GPS and network-based)"</string>
+ <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"This app can get your location based on GPS or network location sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"record audio"</string>
+ <string name="permdesc_recordAudio" msgid="4245930455135321433">"This app can record audio using the microphone at any time."</string>
+ <string name="permlab_sim_communication" msgid="2935852302216852065">"send commands to the SIM"</string>
+ <string name="permdesc_sim_communication" msgid="5725159654279639498">"Allows the app to send commands to the SIM. This is very dangerous."</string>
+ <string name="permlab_camera" msgid="3616391919559751192">"take pictures and videos"</string>
+ <string name="permdesc_camera" msgid="5392231870049240670">"This app can take pictures and record videos using the camera at any time."</string>
+ <string name="permlab_vibrate" msgid="7696427026057705834">"control vibration"</string>
+ <string name="permdesc_vibrate" msgid="6284989245902300945">"Allows the app to control the vibrator."</string>
+ <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+ <string name="permlab_accessImsCallService" msgid="3574943847181793918">"access IMS call service"</string>
+ <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Allows the app to use the IMS service to make calls without your intervention."</string>
+ <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
+ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active, and the remote number connected by a call."</string>
+ <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"route calls through the system"</string>
+ <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Allows the app to route its calls through the system in order to improve the calling experience."</string>
+ <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"read phone numbers"</string>
+ <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Allows the app to access the phone numbers of the device."</string>
+ <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"prevent TV from sleeping"</string>
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Allows the app to prevent the TV from going to sleep."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Allows the app to prevent the phone from going to sleep."</string>
+ <string name="permlab_transmitIr" msgid="7545858504238530105">"transmit infrared"</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Allows the app to use the tablet\'s infrared transmitter."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Allows the app to use the TV\'s infrared transmitter."</string>
+ <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Allows the app to use the phone\'s infrared transmitter."</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"set wallpaper"</string>
+ <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Allows the app to set the system wallpaper."</string>
+ <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"adjust your wallpaper size"</string>
+ <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Allows the app to set the system wallpaper size hints."</string>
+ <string name="permlab_setTimeZone" msgid="2945079801013077340">"set time zone"</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Allows the app to change the tablet\'s time zone."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Allows the app to change the TV\'s time zone."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Allows the app to change the phone\'s time zone."</string>
+ <string name="permlab_getAccounts" msgid="1086795467760122114">"find accounts on the device"</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Allows the app to get the list of accounts known by the tablet. This may include any accounts created by applications you have installed."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Allows the app to get the list of accounts known by the TV. This may include any accounts created by applications you have installed."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Allows the app to get the list of accounts known by the phone. This may include any accounts created by applications you have installed."</string>
+ <string name="permlab_accessNetworkState" msgid="4951027964348974773">"view network connections"</string>
+ <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Allows the app to view information about network connections such as which networks exist and are connected."</string>
+ <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"have full network access"</string>
+ <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Allows the app to create network sockets and use custom network protocols. The browser and other applications provide means to send data to the internet, so this permission is not required to send data to the internet."</string>
+ <string name="permlab_changeNetworkState" msgid="958884291454327309">"change network connectivity"</string>
+ <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Allows the app to change the state of network connectivity."</string>
+ <string name="permlab_changeTetherState" msgid="5952584964373017960">"change tethered connectivity"</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Allows the app to change the state of tethered network connectivity."</string>
+ <string name="permlab_accessWifiState" msgid="5202012949247040011">"view Wi-Fi connections"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Allows the app to view information about Wi-Fi networking, such as whether Wi-Fi is enabled and name of connected Wi-Fi devices."</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"connect and disconnect from Wi-Fi"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Allows the app to connect to and disconnect from Wi-Fi access points and to make changes to device configuration for Wi-Fi networks."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"allow Wi-Fi Multicast reception"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your tablet. It uses more power than the non-multicast mode."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your TV. It uses more power than the non-multicast mode."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your phone. It uses more power than the non-multicast mode."</string>
+ <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"access Bluetooth settings"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Allows the app to configure the local Bluetooth tablet, and to discover and pair with remote devices."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Allows the app to configure the local Bluetooth TV, and to discover and pair with remote devices."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Allows the app to configure the local Bluetooth phone, and to discover and pair with remote devices."</string>
+ <string name="permlab_accessWimaxState" msgid="4195907010610205703">"connect and disconnect from WiMAX"</string>
+ <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Allows the app to determine whether WiMAX is enabled and information about any WiMAX networks that are connected."</string>
+ <string name="permlab_changeWimaxState" msgid="340465839241528618">"change WiMAX state"</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Allows the app to connect the tablet to and disconnect the tablet from WiMAX networks."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Allows the app to connect the TV to and disconnect the TV from WiMAX networks."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Allows the app to connect the phone to and disconnect the phone from WiMAX networks."</string>
+ <string name="permlab_bluetooth" msgid="6127769336339276828">"pair with Bluetooth devices"</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Allows the app to view the configuration of Bluetooth on the tablet, and to make and accept connections with paired devices."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Allows the app to view the configuration of Bluetooth on the TV, and to make and accept connections with paired devices."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Allows the app to view the configuration of the Bluetooth on the phone, and to make and accept connections with paired devices."</string>
+ <string name="permlab_nfc" msgid="4423351274757876953">"control Near Field Communication"</string>
+ <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards, and readers."</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
+ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
+ <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
+ <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Allows the app to invoke methods to add and delete fingerprint templates for use."</string>
+ <string name="permlab_useFingerprint" msgid="3150478619915124905">"use fingerprint hardware"</string>
+ <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Allows the app to use fingerprint hardware for authentication"</string>
+ <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Partial fingerprint detected. Please try again."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Couldn\'t process fingerprint. Please try again."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerprint sensor is dirty. Please clean and try again."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger moved too fast. Please try again."</string>
+ <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger moved too slow. Please try again."</string>
+ <string-array name="fingerprint_acquired_vendor">
+ </string-array>
+ <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerprint hardware not available."</string>
+ <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerprint can\'t be stored. Please remove an existing fingerprint."</string>
+ <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint time out reached. Try again."</string>
+ <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation canceled."</string>
+ <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
+ <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Too many attempts. Fingerprint sensor disabled."</string>
+ <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
+ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string-array name="fingerprint_error_vendor">
+ </string-array>
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string>
+ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
+ <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
+ <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string>
+ <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable sync of the People app with an account."</string>
+ <string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
+ <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"read the contents of your USB storage"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"read the contents of your SD card"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Allows the app to read the contents of your USB storage."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Allows the app to read the contents of your SD card."</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modify or delete the contents of your USB storage"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modify or delete the contents of your SD card"</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Allows the app to write to the USB storage."</string>
+ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
+ <string name="permlab_use_sip" msgid="2052499390128979920">"make/receive SIP calls"</string>
+ <string name="permdesc_use_sip" msgid="2297804849860225257">"Allows the app to make and receive SIP calls."</string>
+ <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"register new telecom SIM connections"</string>
+ <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Allows the app to register new telecom SIM connections."</string>
+ <string name="permlab_register_call_provider" msgid="108102120289029841">"register new telecom connections"</string>
+ <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Allows the app to register new telecom connections."</string>
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"manage telecom connections"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Allows the app to manage telecom connections."</string>
+ <string name="permlab_bind_incall_service" msgid="6773648341975287125">"interact with in-call screen"</string>
+ <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Allows the app to control when and how the user sees the in-call screen."</string>
+ <string name="permlab_bind_connection_service" msgid="3557341439297014940">"interact with telephony services"</string>
+ <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Allows the app to interact with telephony services to make/receive calls."</string>
+ <string name="permlab_control_incall_experience" msgid="9061024437607777619">"provide an in-call user experience"</string>
+ <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Allows the app to provide an in-call user experience."</string>
+ <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"read historical network usage"</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Allows the app to read historical network usage for specific networks and apps."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"manage network policy"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Allows the app to manage network policies and define app-specific rules."</string>
+ <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modify network usage accounting"</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Allows the app to modify how network usage is accounted against apps. Not for use by normal apps."</string>
+ <string name="permlab_accessNotifications" msgid="7673416487873432268">"access notifications"</string>
+ <string name="permdesc_accessNotifications" msgid="458457742683431387">"Allows the app to retrieve, examine, and clear notifications, including those posted by other apps."</string>
+ <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bind to a notification listener service"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"bind to a condition provider service"</string>
+ <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindDreamService" msgid="4153646965978563462">"bind to a dream service"</string>
+ <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
+ <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+ <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+ <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
+ <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"access DRM certificates"</string>
+ <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Allows an application to provision and use DRM certficates. Should never be needed for normal apps."</string>
+ <string name="permlab_handoverStatus" msgid="7820353257219300883">"receive Android Beam transfer status"</string>
+ <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Allows this application to receive information about current Android Beam transfers"</string>
+ <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remove DRM certificates"</string>
+ <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"bind to a carrier messaging service"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"bind to carrier services"</string>
+ <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Allows the holder to bind to carrier services. Should never be needed for normal apps."</string>
+ <string name="permlab_access_notification_policy" msgid="4247510821662059671">"access Do Not Disturb"</string>
+ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
+ <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
+ <string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the tablet or erase all the tablet\'s data if too many incorrect passwords are typed."</string>
+ <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the TV or erase all the TV\'s data if too many incorrect passwords are typed."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitor the number of incorrect passwords typed. when unlocking the screen, and lock the phone or erase all the phone\'s data if too many incorrect passwords are typed."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the tablet or erase all this user\'s data if too many incorrect passwords are typed."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the TV or erase all this user\'s data if too many incorrect passwords are typed."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Monitor the number of incorrect passwords typed when unlocking the screen, and lock the phone or erase all this user\'s data if too many incorrect passwords are typed."</string>
+ <string name="policylab_resetPassword" msgid="4934707632423915395">"Change the screen lock"</string>
+ <string name="policydesc_resetPassword" msgid="1278323891710619128">"Change the screen lock."</string>
+ <string name="policylab_forceLock" msgid="2274085384704248431">"Lock the screen"</string>
+ <string name="policydesc_forceLock" msgid="1141797588403827138">"Control how and when the screen locks."</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Erase all data"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Erase the tablet\'s data without warning by performing a factory data reset."</string>
+ <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Erase the TV\'s data without warning by performing a factory data reset."</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Erase the phone\'s data without warning by performing a factory data reset."</string>
+ <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Erase user data"</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Erase this user\'s data on this tablet without warning."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Erase this user\'s data on this TV without warning."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Erase this user\'s data on this phone without warning."</string>
+ <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Set the device global proxy"</string>
+ <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Set the device global proxy to be used while policy is enabled. Only the device owner can set the global proxy."</string>
+ <string name="policylab_expirePassword" msgid="5610055012328825874">"Set screen lock password expiration"</string>
+ <string name="policydesc_expirePassword" msgid="5367525762204416046">"Change how frequently the screen lock password, PIN, or pattern must be changed."</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Set storage encryption"</string>
+ <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Require that stored app data be encrypted."</string>
+ <string name="policylab_disableCamera" msgid="6395301023152297826">"Disable cameras"</string>
+ <string name="policydesc_disableCamera" msgid="2306349042834754597">"Prevent use of all device cameras."</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Disable some screen lock features"</string>
+ <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Prevent use of some screen lock features."</string>
+ <string-array name="phoneTypes">
+ <item msgid="8901098336658710359">"Home"</item>
+ <item msgid="869923650527136615">"Mobile"</item>
+ <item msgid="7897544654242874543">"Work"</item>
+ <item msgid="1103601433382158155">"Work Fax"</item>
+ <item msgid="1735177144948329370">"Home Fax"</item>
+ <item msgid="603878674477207394">"Pager"</item>
+ <item msgid="1650824275177931637">"Other"</item>
+ <item msgid="9192514806975898961">"Custom"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item msgid="8073994352956129127">"Home"</item>
+ <item msgid="7084237356602625604">"Work"</item>
+ <item msgid="1112044410659011023">"Other"</item>
+ <item msgid="2374913952870110618">"Custom"</item>
+ </string-array>
+ <string-array name="postalAddressTypes">
+ <item msgid="6880257626740047286">"Home"</item>
+ <item msgid="5629153956045109251">"Work"</item>
+ <item msgid="4966604264500343469">"Other"</item>
+ <item msgid="4932682847595299369">"Custom"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item msgid="1738585194601476694">"Home"</item>
+ <item msgid="1359644565647383708">"Work"</item>
+ <item msgid="7868549401053615677">"Other"</item>
+ <item msgid="3145118944639869809">"Custom"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item msgid="7546335612189115615">"Work"</item>
+ <item msgid="4378074129049520373">"Other"</item>
+ <item msgid="3455047468583965104">"Custom"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item msgid="8595261363518459565">"AIM"</item>
+ <item msgid="7390473628275490700">"Windows Live"</item>
+ <item msgid="7882877134931458217">"Yahoo"</item>
+ <item msgid="5035376313200585242">"Skype"</item>
+ <item msgid="7532363178459444943">"QQ"</item>
+ <item msgid="3713441034299660749">"Google Talk"</item>
+ <item msgid="2506857312718630823">"ICQ"</item>
+ <item msgid="1648797903785279353">"Jabber"</item>
+ </string-array>
+ <string name="phoneTypeCustom" msgid="1644738059053355820">"Custom"</string>
+ <string name="phoneTypeHome" msgid="2570923463033985887">"Home"</string>
+ <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobile"</string>
+ <string name="phoneTypeWork" msgid="8863939667059911633">"Work"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Work Fax"</string>
+ <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Home Fax"</string>
+ <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string>
+ <string name="phoneTypeOther" msgid="1544425847868765990">"Other"</string>
+ <string name="phoneTypeCallback" msgid="2712175203065678206">"Callback"</string>
+ <string name="phoneTypeCar" msgid="8738360689616716982">"Car"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Company Main"</string>
+ <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+ <string name="phoneTypeMain" msgid="6766137010628326916">"Main"</string>
+ <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Other Fax"</string>
+ <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+ <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
+ <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Work Mobile"</string>
+ <string name="phoneTypeWorkPager" msgid="649938731231157056">"Work Pager"</string>
+ <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string>
+ <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"Custom"</string>
+ <string name="eventTypeBirthday" msgid="2813379844211390740">"Birthday"</string>
+ <string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversary"</string>
+ <string name="eventTypeOther" msgid="7388178939010143077">"Other"</string>
+ <string name="emailTypeCustom" msgid="8525960257804213846">"Custom"</string>
+ <string name="emailTypeHome" msgid="449227236140433919">"Home"</string>
+ <string name="emailTypeWork" msgid="3548058059601149973">"Work"</string>
+ <string name="emailTypeOther" msgid="2923008695272639549">"Other"</string>
+ <string name="emailTypeMobile" msgid="119919005321166205">"Mobile"</string>
+ <string name="postalTypeCustom" msgid="8903206903060479902">"Custom"</string>
+ <string name="postalTypeHome" msgid="8165756977184483097">"Home"</string>
+ <string name="postalTypeWork" msgid="5268172772387694495">"Work"</string>
+ <string name="postalTypeOther" msgid="2726111966623584341">"Other"</string>
+ <string name="imTypeCustom" msgid="2074028755527826046">"Custom"</string>
+ <string name="imTypeHome" msgid="6241181032954263892">"Home"</string>
+ <string name="imTypeWork" msgid="1371489290242433090">"Work"</string>
+ <string name="imTypeOther" msgid="5377007495735915478">"Other"</string>
+ <string name="imProtocolCustom" msgid="6919453836618749992">"Custom"</string>
+ <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+ <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+ <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
+ <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+ <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+ <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
+ <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+ <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+ <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
+ <string name="orgTypeWork" msgid="29268870505363872">"Work"</string>
+ <string name="orgTypeOther" msgid="3951781131570124082">"Other"</string>
+ <string name="orgTypeCustom" msgid="225523415372088322">"Custom"</string>
+ <string name="relationTypeCustom" msgid="3542403679827297300">"Custom"</string>
+ <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistant"</string>
+ <string name="relationTypeBrother" msgid="8757913506784067713">"Brother"</string>
+ <string name="relationTypeChild" msgid="1890746277276881626">"Child"</string>
+ <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Domestic Partner"</string>
+ <string name="relationTypeFather" msgid="5228034687082050725">"Father"</string>
+ <string name="relationTypeFriend" msgid="7313106762483391262">"Friend"</string>
+ <string name="relationTypeManager" msgid="6365677861610137895">"Manager"</string>
+ <string name="relationTypeMother" msgid="4578571352962758304">"Mother"</string>
+ <string name="relationTypeParent" msgid="4755635567562925226">"Parent"</string>
+ <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"Referred by"</string>
+ <string name="relationTypeRelative" msgid="1799819930085610271">"Relative"</string>
+ <string name="relationTypeSister" msgid="1735983554479076481">"Sister"</string>
+ <string name="relationTypeSpouse" msgid="394136939428698117">"Spouse"</string>
+ <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Custom"</string>
+ <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
+ <string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
+ <string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944">""<font size="17">"Tap to type password"</font>""</string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu then 0."</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Emergency number"</string>
+ <string name="lockscreen_carrier_default" msgid="6169005837238288522">"No service"</string>
+ <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Screen locked."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Press Menu to unlock or place emergency call."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Press Menu to unlock."</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Draw pattern to unlock"</string>
+ <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Emergency"</string>
+ <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Return to call"</string>
+ <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correct!"</string>
+ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
+ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
+ <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Unlock for all features and data"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No SIM card in phone."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insert a SIM card."</string>
+ <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"The SIM card is missing or not readable. Insert a SIM card."</string>
+ <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Unusable SIM card."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+ <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Previous track"</string>
+ <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Next track"</string>
+ <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pause"</string>
+ <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Play"</string>
+ <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Stop"</string>
+ <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Rewind"</string>
+ <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Fast forward"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Emergency calls only"</string>
+ <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Network locked"</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM card is PUK-locked."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+ <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Forgot pattern?"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account unlock"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Too many pattern attempts"</string>
+ <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"To unlock, sign in with your Google account."</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Username (email)"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
+ <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Sign in"</string>
+ <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Invalid username or password."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Checking…"</string>
+ <string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
+ <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
+ <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sound off"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Pattern started"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Pattern cleared"</string>
+ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
+ <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string>
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="granularity_label_character" msgid="7336470535385009523">"character"</string>
+ <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
+ <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+ <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
+ <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
+ <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
+ <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"Reboot"</string>
+ <string name="js_dialog_title" msgid="1987483977834603872">"The page at \"<xliff:g id="TITLE">%s</xliff:g>\" says:"</string>
+ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+ <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirm Navigation"</string>
+ <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Leave this Page"</string>
+ <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Stay on this Page"</string>
+ <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAre you sure you want to navigate away from this page?"</string>
+ <string name="save_password_label" msgid="6860261758665825069">"Confirm"</string>
+ <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Double-tap to zoom in and out."</string>
+ <string name="autofill_this_form" msgid="4616758841157816676">"Autofill"</string>
+ <string name="setup_autofill" msgid="7103495070180590814">"Set up Autofill"</string>
+ <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+ <string name="autofill_province" msgid="2231806553863422300">"Province"</string>
+ <string name="autofill_postal_code" msgid="4696430407689377108">"Postal code"</string>
+ <string name="autofill_state" msgid="6988894195520044613">"State"</string>
+ <string name="autofill_zip_code" msgid="8697544592627322946">"ZIP code"</string>
+ <string name="autofill_county" msgid="237073771020362891">"County"</string>
+ <string name="autofill_island" msgid="4020100875984667025">"Island"</string>
+ <string name="autofill_district" msgid="8400735073392267672">"District"</string>
+ <string name="autofill_department" msgid="5343279462564453309">"Department"</string>
+ <string name="autofill_prefecture" msgid="2028499485065800419">"Prefecture"</string>
+ <string name="autofill_parish" msgid="8202206105468820057">"Parish"</string>
+ <string name="autofill_area" msgid="3547409050889952423">"Area"</string>
+ <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"read your Web bookmarks and history"</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Allows the app to read the history of all URLs that the Browser has visited, and all of the Browser\'s bookmarks. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"write web bookmarks and history"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Allows the app to modify the Browser\'s history or bookmarks stored on your tablet. This may allow the app to erase or modify Browser data. Note: this permission may note be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Allows the app to modify the Browser\'s history or bookmarks stored on your TV. This may allow the app to erase or modify Browser data. Note: this permission may note be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Allows the app to modify the Browser\'s history or bookmarks stored on your phone. This may allow the app to erase or modify Browser data. Note: this permission may note be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+ <string name="permlab_setAlarm" msgid="1379294556362091814">"set an alarm"</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"Allows the app to set an alarm in an installed alarm clock app. Some alarm clock apps may not implement this feature."</string>
+ <string name="permlab_addVoicemail" msgid="5525660026090959044">"add voicemail"</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Allows the app to add messages to your voicemail inbox."</string>
+ <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modify Browser geolocation permissions"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Allows the app to modify the Browser\'s geolocation permissions. Malicious apps may use this to allow sending location information to arbitrary web sites."</string>
+ <string name="save_password_message" msgid="767344687139195790">"Do you want the browser to remember this password?"</string>
+ <string name="save_password_notnow" msgid="6389675316706699758">"Not now"</string>
+ <string name="save_password_remember" msgid="6491879678996749466">"Remember"</string>
+ <string name="save_password_never" msgid="8274330296785855105">"Never"</string>
+ <string name="open_permission_deny" msgid="7374036708316629800">"You don\'t have permission to open this page."</string>
+ <string name="text_copied" msgid="4985729524670131385">"Text copied to clipboard."</string>
+ <string name="more_item_label" msgid="4650918923083320495">"More"</string>
+ <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
+ <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
+ <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
+ <string name="search_go" msgid="8298016669822141719">"Search"</string>
+ <string name="search_hint" msgid="1733947260773056054">"Search…"</string>
+ <string name="searchview_description_search" msgid="6749826639098512120">"Search"</string>
+ <string name="searchview_description_query" msgid="5911778593125355124">"Search query"</string>
+ <string name="searchview_description_clear" msgid="1330281990951833033">"Clear query"</string>
+ <string name="searchview_description_submit" msgid="2688450133297983542">"Submit query"</string>
+ <string name="searchview_description_voice" msgid="2453203695674994440">"Voice search"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Enable Explore by Touch?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone."</string>
+ <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 month ago"</string>
+ <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Before 1 month ago"</string>
+ <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
+ <item quantity="other">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">Last <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+ </plurals>
+ <string name="last_month" msgid="3959346739979055432">"Last month"</string>
+ <string name="older" msgid="5211975022815554840">"Older"</string>
+ <string name="preposition_for_date" msgid="9093949757757445117">"on <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="preposition_for_time" msgid="5506831244263083793">"at <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="preposition_for_year" msgid="5040395640711867177">"in <xliff:g id="YEAR">%s</xliff:g>"</string>
+ <string name="day" msgid="8144195776058119424">"day"</string>
+ <string name="days" msgid="4774547661021344602">"days"</string>
+ <string name="hour" msgid="2126771916426189481">"hour"</string>
+ <string name="hours" msgid="894424005266852993">"hours"</string>
+ <string name="minute" msgid="9148878657703769868">"min"</string>
+ <string name="minutes" msgid="5646001005827034509">"mins"</string>
+ <string name="second" msgid="3184235808021478">"sec"</string>
+ <string name="seconds" msgid="3161515347216589235">"secs"</string>
+ <string name="week" msgid="5617961537173061583">"week"</string>
+ <string name="weeks" msgid="6509623834583944518">"weeks"</string>
+ <string name="year" msgid="4001118221013892076">"year"</string>
+ <string name="years" msgid="6881577717993213522">"years"</string>
+ <string name="now_string_shortest" msgid="8912796667087856402">"now"</string>
+ <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>m</item>
+ </plurals>
+ <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>h</item>
+ </plurals>
+ <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>d</item>
+ </plurals>
+ <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>y</item>
+ </plurals>
+ <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>m</item>
+ </plurals>
+ <plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>h</item>
+ </plurals>
+ <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>d</item>
+ </plurals>
+ <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>y</item>
+ </plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minute ago</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hour ago</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> day ago</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> year ago</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> hour</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> year</item>
+ </plurals>
+ <string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
+ <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
+ <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
+ <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="noon" msgid="7245353528818587908">"noon"</string>
+ <string name="Noon" msgid="3342127745230013127">"Noon"</string>
+ <string name="midnight" msgid="7166259508850457595">"midnight"</string>
+ <string name="Midnight" msgid="5630806906897892201">"Midnight"</string>
+ <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
+ <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+ <string name="selectAll" msgid="6876518925844129331">"Select all"</string>
+ <string name="cut" msgid="3092569408438626261">"Cut"</string>
+ <string name="copy" msgid="2681946229533511987">"Copy"</string>
+ <string name="paste" msgid="5629880836805036433">"Paste"</string>
+ <string name="paste_as_plain_text" msgid="5427792741908010675">"Paste as plain text"</string>
+ <string name="replace" msgid="5781686059063148930">"Replace…"</string>
+ <string name="delete" msgid="6098684844021697789">"Delete"</string>
+ <string name="copyUrl" msgid="2538211579596067402">"Copy URL"</string>
+ <string name="selectTextMode" msgid="1018691815143165326">"Select text"</string>
+ <string name="undo" msgid="7905788502491742328">"Undo"</string>
+ <string name="redo" msgid="7759464876566803888">"Redo"</string>
+ <string name="autofill" msgid="3035779615680565188">"Autofill"</string>
+ <string name="textSelectionCABTitle" msgid="5236850394370820357">"Text selection"</string>
+ <string name="addToDictionary" msgid="4352161534510057874">"Add to dictionary"</string>
+ <string name="deleteText" msgid="6979668428458199034">"Delete"</string>
+ <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
+ <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
+ <string name="email" msgid="4560673117055050403">"Email"</string>
+ <string name="dial" msgid="4204975095406423102">"Phone"</string>
+ <string name="map" msgid="6068210738233985748">"Maps"</string>
+ <string name="browse" msgid="6993590095938149861">"Browser"</string>
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
+ <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure you have 250MB of free space and restart."</string>
+ <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
+ <string name="app_running_notification_text" msgid="1197581823314971177">"Tap for more information or to stop the app."</string>
+ <string name="ok" msgid="5970060430562524910">"OK"</string>
+ <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+ <string name="yes" msgid="5362982303337969312">"OK"</string>
+ <string name="no" msgid="5141531044935541497">"Cancel"</string>
+ <string name="dialog_alert_title" msgid="2049658708609043103">"Attention"</string>
+ <string name="loading" msgid="7933681260296021180">"Loading…"</string>
+ <string name="capital_on" msgid="1544682755514494298">"ON"</string>
+ <string name="capital_off" msgid="6815870386972805832">"OFF"</string>
+ <string name="whichApplication" msgid="4533185947064773386">"Complete action using"</string>
+ <string name="whichApplicationNamed" msgid="8260158865936942783">"Complete action using %1$s"</string>
+ <string name="whichApplicationLabel" msgid="7425855495383818784">"Complete action"</string>
+ <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
+ <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
+ <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
+ <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
+ <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
+ <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Edit"</string>
+ <string name="whichSendApplication" msgid="6902512414057341668">"Share with"</string>
+ <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Share with %1$s"</string>
+ <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Share"</string>
+ <string name="whichSendToApplication" msgid="8272422260066642057">"Send using"</string>
+ <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"Send using %1$s"</string>
+ <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"Send"</string>
+ <string name="whichHomeApplication" msgid="4307587691506919691">"Select a Home app"</string>
+ <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Use %1$s as Home"</string>
+ <string name="whichHomeApplicationLabel" msgid="809529747002918649">"Capture image"</string>
+ <string name="whichImageCaptureApplication" msgid="3680261417470652882">"Capture image with"</string>
+ <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"Capture image with %1$s"</string>
+ <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"Capture image"</string>
+ <string name="alwaysUse" msgid="4583018368000610438">"Use by default for this action."</string>
+ <string name="use_a_different_app" msgid="8134926230585710243">"Use a different app"</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Clear default in System settings > Apps > Downloaded."</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"Choose an action"</string>
+ <string name="chooseUsbActivity" msgid="6894748416073583509">"Choose an app for the USB device"</string>
+ <string name="noApplications" msgid="2991814273936504689">"No apps can perform this action."</string>
+ <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> has stopped"</string>
+ <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> has stopped"</string>
+ <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> keeps stopping"</string>
+ <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> keeps stopping"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Open app again"</string>
+ <string name="aerr_report" msgid="5371800241488400617">"Send feedback"</string>
+ <string name="aerr_close" msgid="2991640326563991340">"Close"</string>
+ <string name="aerr_mute" msgid="1974781923723235953">"Mute until device restarts"</string>
+ <string name="aerr_wait" msgid="3199956902437040261">"Wait"</string>
+ <string name="aerr_close_app" msgid="3269334853724920302">"Close app"</string>
+ <string name="anr_title" msgid="4351948481459135709"></string>
+ <string name="anr_activity_application" msgid="8493290105678066167">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding"</string>
+ <string name="anr_activity_process" msgid="1622382268908620314">"<xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding"</string>
+ <string name="anr_application_process" msgid="6417199034861140083">"<xliff:g id="APPLICATION">%1$s</xliff:g> isn\'t responding"</string>
+ <string name="anr_process" msgid="6156880875555921105">"Process <xliff:g id="PROCESS">%1$s</xliff:g> isn\'t responding"</string>
+ <string name="force_close" msgid="8346072094521265605">"OK"</string>
+ <string name="report" msgid="4060218260984795706">"Report"</string>
+ <string name="wait" msgid="7147118217226317732">"Wait"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive.\n\nDo you want to close it?"</string>
+ <string name="launch_warning_title" msgid="1547997780506713581">"App redirected"</string>
+ <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is now running."</string>
+ <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was originally launched."</string>
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scale"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Always show"</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Re-enable this in System settings > Apps > Downloaded."</string>
+ <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly."</string>
+ <string name="unsupported_display_size_show" msgid="7969129195360353041">"Always show"</string>
+ <string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced StrictMode policy."</string>
+ <string name="smv_process" msgid="5120397012047462446">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has has violated its self-enforced StrictMode policy."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Android is upgrading…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
+ <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizing storage."</string>
+ <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Finishing Android update…"</string>
+ <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Some apps may not work properly until the upgrade finishes"</string>
+ <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> is upgrading…"</string>
+ <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizing app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="android_preparing_apk" msgid="8162599310274079154">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
+ <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
+ <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+ <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tap to switch to app"</string>
+ <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
+ <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
+ <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+ <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
+ <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+ <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+ <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+ <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump has been collected; tap to share"</string>
+ <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
+ <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+ <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
+ <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
+ <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
+ <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Playing through Bluetooth"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Silent ringtone set"</string>
+ <string name="volume_call" msgid="3941680041282788711">"In-call volume"</string>
+ <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth in-call volume"</string>
+ <string name="volume_alarm" msgid="1985191616042689100">"Alarm volume"</string>
+ <string name="volume_notification" msgid="2422265656744276715">"Notification volume"</string>
+ <string name="volume_unknown" msgid="1400219669770445902">"Volume"</string>
+ <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth volume"</string>
+ <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Ringtone volume"</string>
+ <string name="volume_icon_description_incall" msgid="8890073218154543397">"Call volume"</string>
+ <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
+ <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
+ <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
+ <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarm sounds"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Notification sounds"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Unknown"</string>
+ <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+ <item quantity="other">Wi-Fi networks available</item>
+ <item quantity="one">Wi-Fi network available</item>
+ </plurals>
+ <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+ <item quantity="other">Open Wi-Fi networks available</item>
+ <item quantity="one">Open Wi-Fi network available</item>
+ </plurals>
+ <string name="wifi_available_title" msgid="3817100557900599505">"Connect to open Wi‑Fi network"</string>
+ <string name="wifi_available_title_connecting" msgid="1557292688310330032">"Connecting to open Wi‑Fi network"</string>
+ <string name="wifi_available_title_connected" msgid="7542672851522241548">"Connected to Wi‑Fi network"</string>
+ <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Could not connect to Wi‑Fi network"</string>
+ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
+ <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
+ <string name="wifi_available_action_all_networks" msgid="1100098935861622985">"All Networks"</string>
+ <string name="wifi_available_sign_in" msgid="9157196203958866662">"Sign in to Wi-Fi network"</string>
+ <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
+ <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+ <skip />
+ <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi has no Internet access"</string>
+ <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap for options"</string>
+ <string name="network_switch_metered" msgid="4671730921726992671">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+ <string name="network_switch_metered_detail" msgid="5325661434777870353">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+ <string name="network_switch_metered_toast" msgid="5779283181685974304">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+ <string-array name="network_switch_type_name">
+ <item msgid="3979506840912951943">"mobile data"</item>
+ <item msgid="75483255295529161">"Wi-Fi"</item>
+ <item msgid="6862614801537202646">"Bluetooth"</item>
+ <item msgid="5447331121797802871">"Ethernet"</item>
+ <item msgid="8257233890381651999">"VPN"</item>
+ </string-array>
+ <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"an unknown network type"</string>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+ <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Allow connection?"</string>
+ <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Application %1$s would like to connect to Wifi Network %2$s"</string>
+ <string name="wifi_connect_default_application" msgid="7143109390475484319">"An application"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct is on"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Tap for settings"</string>
+ <string name="accept" msgid="1645267259272829559">"Accept"</string>
+ <string name="decline" msgid="2112225451706137894">"Decline"</string>
+ <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation sent"</string>
+ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitation to connect"</string>
+ <string name="wifi_p2p_from_message" msgid="570389174731951769">"From:"</string>
+ <string name="wifi_p2p_to_message" msgid="248968974522044099">"To:"</string>
+ <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Type the required PIN:"</string>
+ <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"The TV will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="select_character" msgid="3365550120617701745">"Insert character"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"Sending SMS messages"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is sending a large number of SMS messages. Do you want to allow this app to continue sending messages?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Allow"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Deny"</string>
+ <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> would like to send a message to <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
+ <string name="sms_short_code_details" msgid="5873295990846059400">"This "<b>"may cause charges"</b>" on your mobile account."</string>
+ <string name="sms_premium_short_code_details" msgid="7869234868023975">""<b>"This will cause charges on your mobile account."</b>""</string>
+ <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Send"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Cancel"</string>
+ <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Remember my choice"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"You can change this later in Settings > Apps"</string>
+ <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Always Allow"</string>
+ <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Never Allow"</string>
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM card removed"</string>
+ <string name="sim_removed_message" msgid="2333164559970958645">"The mobile network will be unavailable until you restart with a valid SIM card inserted."</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Done"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM card added"</string>
+ <string name="sim_added_message" msgid="6599945301141050216">"Restart your device to access the mobile network."</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Restart"</string>
+ <string name="carrier_app_dialog_message" msgid="7066156088266319533">"To get your new SIM working properly, you\'ll need to install and open an app from your carrier."</string>
+ <string name="carrier_app_dialog_button" msgid="7900235513678617329">"GET THE APP"</string>
+ <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"NOT NOW"</string>
+ <string name="carrier_app_notification_title" msgid="8921767385872554621">"New SIM inserted"</string>
+ <string name="carrier_app_notification_text" msgid="1132487343346050225">"Tap to set it up"</string>
+ <string name="time_picker_dialog_title" msgid="8349362623068819295">"Set time"</string>
+ <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
+ <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
+ <string name="date_time_done" msgid="2507683751759308828">"Done"</string>
+ <string name="perms_new_perm_prefix" msgid="8257740710754301407">""<font size="12" fgcolor="#ff33b5e5">"NEW: "</font>""</string>
+ <string name="perms_description_app" msgid="5139836143293299417">"Provided by <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="no_permissions" msgid="7283357728219338112">"No permissions required"</string>
+ <string name="perm_costs_money" msgid="4902470324142151116">"this may cost you money"</string>
+ <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+ <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB charging this device"</string>
+ <string name="usb_supplying_notification_title" msgid="5310642257296510271">"USB supplying power to attached device"</string>
+ <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB for file transfer"</string>
+ <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB for photo transfer"</string>
+ <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
+ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
+ <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analog audio accessory detected"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"The attached device is not compatible with this phone. Tap to learn more."</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
+ <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
+ <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Taking bug report…"</string>
+ <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Share bug report?"</string>
+ <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sharing bug report…"</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Your admin requested a bug report to help troubleshoot this device. Apps and data may be shared."</string>
+ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHARE"</string>
+ <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"DECLINE"</string>
+ <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
+ <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
+ <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configure physical keyboard"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
+ <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Display over other apps"</string>
+ <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> displaying over other apps"</string>
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> is displaying over other apps"</string>
+ <string name="alert_windows_notification_message" msgid="8917232109522912560">"If you don’t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
+ <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"TURN OFF"</string>
+ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparing <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Checking for errors"</string>
+ <string name="ext_media_new_notification_message" msgid="7589986898808506239">"New <xliff:g id="NAME">%s</xliff:g> detected"</string>
+ <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"For transferring photos and media"</string>
+ <string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"Corrupted <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> is corrupt. Tap to fix."</string>
+ <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> is corrupt. Select to fix."</string>
+ <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"Unsupported <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Tap to set up in a supported format."</string>
+ <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"This device doesn’t support this <xliff:g id="NAME">%s</xliff:g>. Select to set up in a supported format."</string>
+ <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> unexpectedly removed"</string>
+ <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Unmount <xliff:g id="NAME">%s</xliff:g> before removing to avoid data loss"</string>
+ <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"Removed <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> removed; insert a new one"</string>
+ <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Still ejecting <xliff:g id="NAME">%s</xliff:g>…"</string>
+ <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Don\'t remove"</string>
+ <string name="ext_media_init_action" msgid="7952885510091978278">"Set up"</string>
+ <string name="ext_media_unmount_action" msgid="1121883233103278199">"Eject"</string>
+ <string name="ext_media_browse_action" msgid="8322172381028546087">"Explore"</string>
+ <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> missing"</string>
+ <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinsert this device"</string>
+ <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Moving <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_title" msgid="1022809140035962662">"Moving data"</string>
+ <string name="ext_media_move_success_title" msgid="8575300932957954671">"Move complete"</string>
+ <string name="ext_media_move_success_message" msgid="4199002148206265426">"Data moved to <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Couldn\'t move data"</string>
+ <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Data left at original location"</string>
+ <string name="ext_media_status_removed" msgid="6576172423185918739">"Removed"</string>
+ <string name="ext_media_status_unmounted" msgid="2551560878416417752">"Ejected"</string>
+ <string name="ext_media_status_checking" msgid="6193921557423194949">"Checking…"</string>
+ <string name="ext_media_status_mounted" msgid="7253821726503179202">"Ready"</string>
+ <string name="ext_media_status_mounted_ro" msgid="8020978752406021015">"Read-only"</string>
+ <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"Removed unsafely"</string>
+ <string name="ext_media_status_unmountable" msgid="805594039236667894">"Corrupted"</string>
+ <string name="ext_media_status_unsupported" msgid="4691436711745681828">"Unsupported"</string>
+ <string name="ext_media_status_ejecting" msgid="5463887263101234174">"Ejecting…"</string>
+ <string name="ext_media_status_formatting" msgid="1085079556538644861">"Formatting…"</string>
+ <string name="ext_media_status_missing" msgid="5638633895221670766">"Not inserted"</string>
+ <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string>
+ <string name="permlab_route_media_output" msgid="6243022988998972085">"route media output"</string>
+ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string>
+ <string name="permlab_readInstallSessions" msgid="3713753067455750349">"read install sessions"</string>
+ <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Allows an application to read install sessions. This allows it to see details about active package installations."</string>
+ <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"request install packages"</string>
+ <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Allows an application to request installation of packages."</string>
+ <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"request delete packages"</string>
+ <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"Allows an application to request deletion of packages."</string>
+ <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"ask to ignore battery optimizations"</string>
+ <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Allows an app to ask for permission to ignore battery optimizations for that app."</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Tap twice for zoom control"</string>
+ <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string>
+ <string name="ime_action_go" msgid="8320845651737369027">"Go"</string>
+ <string name="ime_action_search" msgid="658110271822807811">"Search"</string>
+ <string name="ime_action_send" msgid="2316166556349314424">"Send"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"Next"</string>
+ <string name="ime_action_done" msgid="8971516117910934605">"Done"</string>
+ <string name="ime_action_previous" msgid="1443550039250105948">"Prev"</string>
+ <string name="ime_action_default" msgid="2840921885558045721">"Execute"</string>
+ <string name="dial_number_using" msgid="5789176425167573586">"Dial number\nusing <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="create_contact_using" msgid="4947405226788104538">"Create contact\nusing <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"The following one or more apps request permission to access your account, now and in the future."</string>
+ <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Do you want to allow this request?"</string>
+ <string name="grant_permissions_header_text" msgid="6874497408201826708">"Access request"</string>
+ <string name="allow" msgid="7225948811296386551">"Allow"</string>
+ <string name="deny" msgid="2081879885755434506">"Deny"</string>
+ <string name="permission_request_notification_title" msgid="6486759795926237907">"Permission requested"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permission requested\nfor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+ <string name="forward_intent_to_owner" msgid="1207197447013960896">"You\'re using this app outside of your work profile"</string>
+ <string name="forward_intent_to_work" msgid="621480743856004612">"You\'re using this app in your work profile"</string>
+ <string name="input_method_binding_label" msgid="1283557179944992649">"Input method"</string>
+ <string name="sync_binding_label" msgid="3687969138375092423">"Sync"</string>
+ <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibility"</string>
+ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
+ <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string>
+ <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string>
+ <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR listener"</string>
+ <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Condition provider"</string>
+ <string name="notification_ranker_binding_label" msgid="774540592299064747">"Notification ranker service"</string>
+ <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string>
+ <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string>
+ <string name="vpn_text" msgid="1610714069627824309">"Tap to manage the network."</string>
+ <string name="vpn_text_long" msgid="4907843483284977618">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Tap to manage the network."</string>
+ <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Always-on VPN connecting…"</string>
+ <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN connected"</string>
+ <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Always-on VPN disconnected"</string>
+ <string name="vpn_lockdown_error" msgid="6009249814034708175">"Always-on VPN error"</string>
+ <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tap to set up"</string>
+ <string name="upload_file" msgid="2897957172366730416">"Choose file"</string>
+ <string name="no_file_chosen" msgid="6363648562170759465">"No file chosen"</string>
+ <string name="reset" msgid="2448168080964209908">"Reset"</string>
+ <string name="submit" msgid="1602335572089911941">"Submit"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Car mode enabled"</string>
+ <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
+ <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
+ <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
+ <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
+ <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
+ <string name="no_matches" msgid="8129421908915840737">"No matches"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"Find on page"</string>
+ <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
+ <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="one">1 match</item>
+ </plurals>
+ <string name="action_mode_done" msgid="7217581640461922289">"Done"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Erasing USB storage…"</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Erasing SD card…"</string>
+ <string name="share" msgid="1778686618230011964">"Share"</string>
+ <string name="find" msgid="4808270900322985960">"Find"</string>
+ <string name="websearch" msgid="4337157977400211589">"Web Search"</string>
+ <string name="find_next" msgid="5742124618942193978">"Find next"</string>
+ <string name="find_previous" msgid="2196723669388360506">"Find previous"</string>
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Location request from <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Location request"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Requested by <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Delete limit exceeded"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"There are <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> deleted items for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. What do you want to do?"</string>
+ <string name="sync_really_delete" msgid="2572600103122596243">"Delete the items"</string>
+ <string name="sync_undo_deletes" msgid="2941317360600338602">"Undo the deletes"</string>
+ <string name="sync_do_nothing" msgid="3743764740430821845">"Do nothing for now"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Choose an account"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"Add an account"</string>
+ <string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string>
+ <string name="number_picker_increment_button" msgid="2412072272832284313">"Increase"</string>
+ <string name="number_picker_decrement_button" msgid="476050778386779067">"Decrease"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> touch & hold."</string>
+ <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Slide up to increase and down to decrease."</string>
+ <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Increase minute"</string>
+ <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Decrease minute"</string>
+ <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Increase hour"</string>
+ <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Decrease hour"</string>
+ <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Set PM"</string>
+ <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Set AM"</string>
+ <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Increase month"</string>
+ <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Decrease month"</string>
+ <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Increase day"</string>
+ <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Decrease day"</string>
+ <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Increase year"</string>
+ <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Decrease year"</string>
+ <string name="date_picker_prev_month_button" msgid="2858244643992056505">"Previous month"</string>
+ <string name="date_picker_next_month_button" msgid="5559507736887605055">"Next month"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Choose an app"</string>
+ <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Couldn\'t launch <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch & hold."</string>
+ <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string>
+ <string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
+ <string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
+ <string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</string>
+ <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
+ <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
+ <string name="storage_internal" msgid="3570990907910199483">"Internal shared storage"</string>
+ <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
+ <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD card"</string>
+ <string name="storage_usb_drive" msgid="6261899683292244209">"USB drive"</string>
+ <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB drive"</string>
+ <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string>
+ <string name="data_usage_warning_title" msgid="3620440638180218181">"Data usage alert"</string>
+ <string name="data_usage_warning_body" msgid="6660692274311972007">"Tap to view usage and settings."</string>
+ <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G data limit reached"</string>
+ <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G data limit reached"</string>
+ <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Mobile data limit reached"</string>
+ <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi data limit reached"</string>
+ <string name="data_usage_limit_body" msgid="291731708279614081">"Data paused for rest of cycle"</string>
+ <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G data limit exceeded"</string>
+ <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G data limit exceeded"</string>
+ <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobile data limit exceeded"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi data limit exceeded"</string>
+ <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> over specified limit."</string>
+ <string name="data_usage_restricted_title" msgid="5965157361036321914">"Background data restricted"</string>
+ <string name="data_usage_restricted_body" msgid="469866376337242726">"Tap to remove restriction."</string>
+ <string name="ssl_certificate" msgid="6510040486049237639">"Security certificate"</string>
+ <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"This certificate is valid."</string>
+ <string name="issued_to" msgid="454239480274921032">"Issued to:"</string>
+ <string name="common_name" msgid="2233209299434172646">"Common name:"</string>
+ <string name="org_name" msgid="6973561190762085236">"Organization:"</string>
+ <string name="org_unit" msgid="7265981890422070383">"Organizational unit:"</string>
+ <string name="issued_by" msgid="2647584988057481566">"Issued by:"</string>
+ <string name="validity_period" msgid="8818886137545983110">"Validity:"</string>
+ <string name="issued_on" msgid="5895017404361397232">"Issued on:"</string>
+ <string name="expires_on" msgid="3676242949915959821">"Expires on:"</string>
+ <string name="serial_number" msgid="758814067660862493">"Serial number:"</string>
+ <string name="fingerprints" msgid="4516019619850763049">"Fingerprints:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 fingerprint:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 fingerprint:"</string>
+ <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"See all"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Choose activity"</string>
+ <string name="share_action_provider_share_with" msgid="5247684435979149216">"Share with"</string>
+ <string name="sending" msgid="3245653681008218030">"Sending…"</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
+ <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
+ <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
+ <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
+ <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
+ <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
+ <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Phone"</string>
+ <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Headphones"</string>
+ <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock speakers"</string>
+ <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+ <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+ <string name="wireless_display_route_description" msgid="9070346425023979651">"Wireless display"</string>
+ <string name="media_route_button_content_description" msgid="591703006349356016">"Cast"</string>
+ <string name="media_route_chooser_title" msgid="1751618554539087622">"Connect to device"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Cast screen to device"</string>
+ <string name="media_route_chooser_searching" msgid="4776236202610828706">"Searching for devices…"</string>
+ <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Settings"</string>
+ <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Disconnect"</string>
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Scanning..."</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Connecting..."</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
+ <string name="media_route_status_not_available" msgid="6739899962681886401">"Not available"</string>
+ <string name="media_route_status_in_use" msgid="4533786031090198063">"In use"</string>
+ <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Built-in Screen"</string>
+ <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Screen"</string>
+ <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
+ <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+ <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%1$d</xliff:g> seconds."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes does not match"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+ <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
+ <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Use Accessibility Shortcut?"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings > Accessibility."</string>
+ <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Turn off Shortcut"</string>
+ <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Use Shortcut"</string>
+ <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
+ <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
+ <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch & hold the Accessibility button."</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
+ <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="user_logging_out_message" msgid="8939524935808875155">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="owner_name" msgid="2716755460376028154">"Owner"</string>
+ <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
+ <string name="error_message_change_not_allowed" msgid="1238035947357923497">"This change isn\'t allowed by your admin"</string>
+ <string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
+ <string name="revoke" msgid="5404479185228271586">"Revoke"</string>
+ <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
+ <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
+ <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string>
+ <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3"</string>
+ <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4"</string>
+ <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5"</string>
+ <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6"</string>
+ <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7"</string>
+ <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8"</string>
+ <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9"</string>
+ <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10"</string>
+ <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0"</string>
+ <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1"</string>
+ <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2"</string>
+ <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3"</string>
+ <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4"</string>
+ <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5"</string>
+ <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6"</string>
+ <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7"</string>
+ <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8"</string>
+ <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9"</string>
+ <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10"</string>
+ <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0"</string>
+ <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1"</string>
+ <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2"</string>
+ <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3"</string>
+ <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4"</string>
+ <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5"</string>
+ <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6"</string>
+ <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7"</string>
+ <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8"</string>
+ <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9"</string>
+ <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10"</string>
+ <string name="mediasize_na_letter" msgid="2841414839888344296">"Letter"</string>
+ <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter"</string>
+ <string name="mediasize_na_legal" msgid="8621364037680465666">"Legal"</string>
+ <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string>
+ <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string>
+ <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid"</string>
+ <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3x5"</string>
+ <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4x6"</string>
+ <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5x8"</string>
+ <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string>
+ <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string>
+ <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string>
+ <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K"</string>
+ <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K"</string>
+ <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1"</string>
+ <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2"</string>
+ <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3"</string>
+ <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4"</string>
+ <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5"</string>
+ <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6"</string>
+ <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7"</string>
+ <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8"</string>
+ <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9"</string>
+ <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10"</string>
+ <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K"</string>
+ <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai"</string>
+ <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai"</string>
+ <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai"</string>
+ <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10"</string>
+ <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9"</string>
+ <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8"</string>
+ <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7"</string>
+ <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6"</string>
+ <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5"</string>
+ <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4"</string>
+ <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3"</string>
+ <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2"</string>
+ <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1"</string>
+ <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0"</string>
+ <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec"</string>
+ <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4"</string>
+ <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3"</string>
+ <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2"</string>
+ <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki"</string>
+ <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku"</string>
+ <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
+ <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
+ <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
+ <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Unknown portrait"</string>
+ <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Unknown landscape"</string>
+ <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
+ <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
+ <string name="reason_service_unavailable" msgid="7824008732243903268">"Print service not enabled"</string>
+ <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> service installed"</string>
+ <string name="print_service_installed_message" msgid="5897362931070459152">"Tap to enable"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Enter admin PIN"</string>
+ <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
+ <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect"</string>
+ <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN"</string>
+ <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
+ <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirm new PIN"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"Create a PIN for modifying restrictions"</string>
+ <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINs don\'t match. Try again."</string>
+ <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN is too short. Must be at least 4 digits."</string>
+ <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
+ <item quantity="other">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
+ <item quantity="one">Try again in 1 second</item>
+ </plurals>
+ <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
+ <string name="immersive_cling_title" msgid="8394201622932303336">"Viewing full screen"</string>
+ <string name="immersive_cling_description" msgid="3482371193207536040">"To exit, swipe down from the top."</string>
+ <string name="immersive_cling_positive" msgid="5016839404568297683">"Got it"</string>
+ <string name="done_label" msgid="2093726099505892398">"Done"</string>
+ <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+ <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+ <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+ <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+ <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+ <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+ <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
+ <string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="lock_to_app_toast" msgid="6820571533009838261">"To unpin this screen, touch & hold Back and Overview buttons"</string>
+ <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"This app can\'t be unpinned"</string>
+ <string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
+ <string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
+ <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Ask for unlock pattern before unpinning"</string>
+ <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
+ <string name="package_installed_device_owner" msgid="6875717669960212648">"Installed by your admin"</string>
+ <string name="package_updated_device_owner" msgid="1847154566357862089">"Updated by your admin"</string>
+ <string name="package_deleted_device_owner" msgid="2307122077550236438">"Deleted by your admin"</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services, and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
+ <string name="data_saver_description" msgid="6015391409098303235">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
+ <string name="data_saver_enable_title" msgid="4674073932722787417">"Turn on Data Saver?"</string>
+ <string name="data_saver_enable_button" msgid="7147735965247211818">"Turn on"</string>
+ <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
+ <item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+ </plurals>
+ <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597">
+ <item quantity="other">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">For 1 min (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
+ <item quantity="other">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">For one hour (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371">
+ <item quantity="other">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">For 1 hr (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
+ </plurals>
+ <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
+ <item quantity="other">For %d minutes</item>
+ <item quantity="one">For one minute</item>
+ </plurals>
+ <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128">
+ <item quantity="other">For %d min</item>
+ <item quantity="one">For 1 min</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
+ <item quantity="other">For %d hours</item>
+ <item quantity="one">For one hour</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217">
+ <item quantity="other">For %d hr</item>
+ <item quantity="one">For 1 hr</item>
+ </plurals>
+ <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
+ <string name="zen_mode_forever" msgid="1916263162129197274">"Until you turn off Do Not Disturb"</string>
+ <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Until you turn off Do Not Disturb"</string>
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
+ <string name="zen_mode_feature_name" msgid="5254089399895895004">"Do not disturb"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Downtime"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Weeknight"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Event"</string>
+ <string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+ <string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
+ <string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
+ <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD request is modified to DIAL request."</string>
+ <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD request is modified to SS request."</string>
+ <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD request is modified to new USSD request."</string>
+ <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
+ <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
+ <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
+ <string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
+ <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
+ <string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
+ <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"More options"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Close overflow"</string>
+ <string name="maximize_button_text" msgid="7543285286182446254">"Maximize"</string>
+ <string name="close_button_text" msgid="3937902162644062866">"Close"</string>
+ <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+ </plurals>
+ <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorized"</string>
+ <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
+ <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
+ <string name="user_creation_account_exists" msgid="1942606193570143289">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
+ <string name="user_creation_adding" msgid="4482658054622099197">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+ <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
+ <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
+ <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
+ <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggested"</string>
+ <string name="language_picker_section_all" msgid="3097279199511617537">"All languages"</string>
+ <string name="region_picker_section_all" msgid="8966316787153001779">"All regions"</string>
+ <string name="locale_search_menu" msgid="2560710726687249178">"Search"</string>
+ <string name="work_mode_off_title" msgid="2615362773958585967">"Turn on work mode?"</string>
+ <string name="work_mode_off_message" msgid="2961559609199223594">"This will turn on your work profile, including apps, background sync, and related features"</string>
+ <string name="work_mode_turn_on" msgid="2062544985670564875">"Turn on"</string>
+ <string name="new_sms_notification_title" msgid="8442817549127555977">"You have new messages"</string>
+ <string name="new_sms_notification_content" msgid="7002938807812083463">"Open SMS app to view"</string>
+ <string name="user_encrypted_title" msgid="9054897468831672082">"Some functionality may be limited"</string>
+ <string name="user_encrypted_message" msgid="4923292604515744267">"Tap to unlock"</string>
+ <string name="user_encrypted_detail" msgid="5708447464349420392">"User data locked"</string>
+ <string name="profile_encrypted_detail" msgid="3700965619978314974">"Work profile locked"</string>
+ <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
+ <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
+ <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
+ <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
+ <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
+ <string name="app_info" msgid="6856026610594615344">"App info"</string>
+ <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
+ <string name="demo_restarting_message" msgid="952118052531642451">"Resetting device…"</string>
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
+ <string name="tooltip_popup_title" msgid="5253721848739260181">"Tooltip"</string>
+ <string name="app_category_game" msgid="5431836943981492993">"Games"</string>
+ <string name="app_category_audio" msgid="1659853108734301647">"Music & Audio"</string>
+ <string name="app_category_video" msgid="2728726078629384196">"Movies & Video"</string>
+ <string name="app_category_image" msgid="4867854544519846048">"Photos & Images"</string>
+ <string name="app_category_social" msgid="5842783057834965912">"Social & Communication"</string>
+ <string name="app_category_news" msgid="7496506240743986873">"News & Magazines"</string>
+ <string name="app_category_maps" msgid="5878491404538024367">"Maps & Navigation"</string>
+ <string name="app_category_productivity" msgid="3742083261781538852">"Productivity"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Device storage"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB debugging"</string>
+ <string name="time_picker_hour_label" msgid="2979075098868106450">"hour"</string>
+ <string name="time_picker_minute_label" msgid="5168864173796598399">"minute"</string>
+ <string name="time_picker_header_text" msgid="143536825321922567">"Set time"</string>
+ <string name="time_picker_input_error" msgid="7574999942502513765">"Enter a valid time"</string>
+ <string name="time_picker_prompt_label" msgid="7588093983899966783">"Type in time"</string>
+ <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
+ <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
+ <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Autofill options"</string>
+ <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Save for Autofill"</string>
+ <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Contents can’t be autofilled"</string>
+ <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"No autofill suggestions"</string>
+ <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+ <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
+ <item quantity="one">One autofill suggestion</item>
+ </plurals>
+ <string name="autofill_save_title" msgid="3345527308992082601">"Save to <b><xliff:g id="LABEL">%1$s</xliff:g></b>?"</string>
+ <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Save <xliff:g id="TYPE">%1$s</xliff:g> to <b><xliff:g id="LABEL">%2$s</xliff:g></b>?"</string>
+ <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Save <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> to <b><xliff:g id="LABEL">%3$s</xliff:g></b>?"</string>
+ <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Save <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g> to <b><xliff:g id="LABEL">%4$s</xliff:g></b>?"</string>
+ <string name="autofill_save_yes" msgid="6398026094049005921">"Save"</string>
+ <string name="autofill_save_no" msgid="2625132258725581787">"No thanks"</string>
+ <string name="autofill_save_type_password" msgid="5288448918465971568">"password"</string>
+ <string name="autofill_save_type_address" msgid="4936707762193009542">"address"</string>
+ <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"credit card"</string>
+ <string name="autofill_save_type_username" msgid="239040540379769562">"username"</string>
+ <string name="autofill_save_type_email_address" msgid="5752949432129262174">"email address"</string>
+ <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Stay calm and seek shelter nearby."</string>
+ <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground."</string>
+ <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Stay calm and seek shelter nearby."</string>
+ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string>
+ <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string>
+ <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
+ <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string>
+ <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string>
+ <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string>
+ <string name="popup_window_default_title" msgid="4874318849712115433">"Popup Window"</string>
+</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6d21cd1..468b01e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil de tu ubicación no ofrece este servicio de forma temporal"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mejorar la recepción, cambia el tipo de red. Selecciona Configuración > Internet y red > Redes móviles > Tipo de red preferido."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Las llamadas con Wi-Fi están activadas"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Las llamadas de emergencia requieren una red móvil."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de llamada"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de llamada de emergencia"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de datos móviles"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Estado de datos móviles"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensajes SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensajes del buzón de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Llamada con Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes mediante Wi-Fi, solicítale a tu proveedor que configure este servicio. Luego, vuelve a activar la Llamada con Wi-Fi en Configuración. (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Regístrate con tu proveedor."</item>
+ <item msgid="7472393097168811593">"Regístrate con tu proveedor (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nueva"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Presiona para ver más opciones."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"El accesorio de audio no es compatible"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Presiona para obtener más información"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se detectó un accesorio de audio analógico"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Presiona para obtener más información."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Presiona para inhabilitar la depuración por USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 3f1de71..2bad008 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil disponible en tu ubicación no ofrece esta opción de forma temporal"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mejorar la recepción, prueba a cambiar el tipo seleccionado en Ajustes > Red e Internet > Redes móviles > Tipo de red preferido."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"La llamada por Wi-Fi está activada"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Necesitas conectarte a una red móvil para hacer llamadas de emergencia."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de llamada"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de llamada de emergencia"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de datos móviles"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Estado de los datos móviles"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensajes SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensajes de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Llamada por Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Para hacer llamadas y enviar mensajes por Wi-Fi, pide antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar la llamada por Wi-Fi en Ajustes. (Código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Regístrate con tu operador"</item>
+ <item msgid="7472393097168811593">"Regístrate con tu operador (código de error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"> 999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nueva"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver más opciones."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accesorio de audio no compatible"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca para obtener más información"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se ha detectado un accesorio de audio analógico"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para inhabilitar la depuración USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index edd53ca..4441834 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Teie asukoha mobiilsidevõrk seda teenust ajutiselt ei paku"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Võrguga ei saa ühendust"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Vastuvõtu parandamiseks muutke valitud tüüpi jaotises Seaded > Võrk ja Internet > Mobiilsidevõrgud > Eelistatud võrgutüüp."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Teatised"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Kõnede suunamine"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hädaolukorra tagasihelistusrežiim"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobiilse andmeside teatised"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-sõnumid"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Kõnepostisõnumid"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"WiFi-kõned"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse. (Veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registreeruge operaatori juures"</item>
+ <item msgid="7472393097168811593">"Registreerige operaatori juures (veakood: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Uus märguanne"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuaalne klaviatuur"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Füüsiline klaviatuur"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Turvalisus"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI jaoks"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Puudutage lisavalikute nägemiseks."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Helitarvikut ei toetata"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Puudutage lisateabe saamiseks"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Tuvastati analoogne helitarvik"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Ühendatud seade ei ühildu selle telefoniga. Puudutage lisateabe saamiseks."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Puudutage USB-silumise keelamiseks."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index db29f4b..c072af8 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Zauden tokiko sare mugikorrak ez du eskaintzen aukera hori une honetan"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ezin da konektatu sarera"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Seinalea hobea izan dadin, aldatu sare mota Ezarpenak > Sareak eta Internet > Sare mugikorrak > Sare mota hobetsia atalean."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Abisuak"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Dei-desbideratzea"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Larrialdi-deiak soilik jasotzeko modua"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Datu mugikorren abisuak"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS mezuak"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Erantzungailuko mezuak"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi bidezko deiak"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Erregistratu operadorearekin"</item>
+ <item msgid="7472393097168811593">"Erregistratu operadorearekin (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ahots-laguntza"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Jakinarazpen berria"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teklatu birtuala"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teklatu fisikoa"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Segurtasuna"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI modurako USBa"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB osagarri batera konektatuta"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Sakatu aukera gehiago ikusteko."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ez da onartzen audio-osagarri hori"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Informazio gehiago lortzeko, sakatu hau"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Audio-osagarri analogiko bat hauteman da"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Erantsitako gailua ez da telefono honekin bateragarria. Sakatu informazio gehiago lortzeko."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Sakatu USB arazketa desgaitzeko."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Akatsen txostena partekatzen…"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d753351..4212814 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"موقتاً توسط شبکه داده دستگاه همراه در مکان شما ارائه نمیشود"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"شبکه دردسترس نیست"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"برای بهبود دریافت، نوع شبکه انتخابشده را در «تنظیمات > شبکه و اینترنت > شبکههای تلفن همراه > نوع شبکه ترجیحی» تغییر دهید."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"تماس ازطریق Wi-Fi فعال است"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"برای انجام تماسهای اضطراری به شبکه تلفن همراه نیاز دارید."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"هشدارها"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"بازارسال تماس"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"حالت پاسخ تماس اضطراری"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"هشدارهای داده تلفن همراه"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"وضعیت داده تلفن همراه"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"پیامکها"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"پیامهای پست صوتی"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"تماس ازطریق Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"برای برقراری تماس و ارسال پیام ازطریق Wi-Fi، ابتدا از شرکت مخابراتی خود بخواهید این سرویس را تنظیم کند. سپس در «تنظیمات»۷ دوباره «تماس ازطریق Wi-Fi» را روشن کنید. (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ثبتنام با شرکت مخابراتی شما"</item>
+ <item msgid="7472393097168811593">"ازطریق شرکت مخابراتیتان ثبتنام کنید (کد خطا: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"۹۹۹+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"اعلان جدید"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"صفحهکلید مجازی"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"صفحهکلید فیزیکی"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"امنیت"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB برای MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"به یک وسیله جانبی USB وصل شده است"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"برای گزینههای بیشتر ضربه بزنید."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"وسیله جانبی صوتی پشتیبانی نمیشود"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"برای اطلاعات بیشتر ضربه بزنید"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"لوازم جانبی صوتی آنالوگ شناسایی شد"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"دستگاه متصلشده با این تلفن سازگار نیست. روی اطلاعات بیشتر، ضربه بزنید."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"اشکالزدایی USB متصل شد"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"برای غیرفعال کردن اشکالزدایی USB ضربه بزنید."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index efffd63..4173ae7 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Sijaintisi mobiiliverkko ei tarjoa tätä tilapäisesti."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ei yhteyttä verkkoon"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Voit yrittää parantaa kuuluvuutta vaihtamalla tyypin asetusta. Valitse Asetukset > Verkko > Internet > Mobiiliverkot > Ensisijainen verkko."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi-puhelut käytössä"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Hätäpuheluihin vaaditaan mobiiliverkko."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Ilmoitukset"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Soitonsiirto"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hätäpuhelujen takaisinsoittotila"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobiilidatailmoitukset"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Mobiilidatan tila"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Tekstiviestit"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Vastaajaviestit"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-puhelut"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa. (Virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+ <item msgid="7472393097168811593">"Rekisteröidy operaattorin asiakkaaksi (virhekoodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ääniapuri"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Uusi ilmoitus"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuaalinen näppäimistö"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyysinen näppäimistö"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Tietosuoja"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB on MIDI-tilassa"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Liitetty USB-laitteeseen"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Näet lisää vaihtoehtoja napauttamalla."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Äänilisälaitetta ei tueta."</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Saat lisätietoja napauttamalla."</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoginen äänilaite havaittu"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Liitetty laite ei ole yhteensopiva puhelimen kanssa. Napauta, niin näet lisätietoja."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Poista USB-vianetsintä käytöstä napauttamalla."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 82f9147..9da0be4 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Ce service est temporairement non offert par le réseau cellulaire à l\'endroit où vous êtes"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible de joindre le réseau"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pour améliorer la réception, essayez de changer le type de réseau sélectionné, sous Paramètres > Réseaux et Internet > Réseaux cellulaires > Type de réseau préféré."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Les appels Wi-Fi sont actifs"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Les appels d\'urgence nécessitent un réseau cellulaire."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Transfert d\'appel"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de rappel d\'urgence"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertes de données cellulaires"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"État des données cellulaires"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Messages texte"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Messages vocaux"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Appels Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+ <item msgid="7472393097168811593">"Inscrivez-vous auprès de votre fournisseur de services (code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. vocale"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nouvelle notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Clavier virtuel"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Clavier physique"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sécurité"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB pour MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Touchez pour afficher plus d\'options."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non pris en charge"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Touchez l\'écran pour obtenir plus d\'information"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Un accessoire audio analogique a été détecté"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"L\'appareil connecté n\'est pas compatible avec ce téléphone. Touchez ici en savoir plus."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Touchez pour désactiver le débogage USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a35e19e..63de4a4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Momentanément non proposé par le réseau mobile à votre position"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible d\'accéder au réseau"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pour améliorer la réception, essayez de modifier le type sélectionné sous Paramètres > Réseau et Internet > Réseaux mobiles > Type de réseau préféré."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Transfert d\'appel"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de rappel d\'urgence"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertes relatives aux données mobiles"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Messages vocaux"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Appels Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres. (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Inscrivez-vous auprès de votre opérateur."</item>
+ <item msgid="7472393097168811593">"Enregistrez-vous auprès de votre opérateur (Code d\'erreur : <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Assistance vocale"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nouvelle notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Clavier virtuel"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Clavier physique"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sécurité"</string>
@@ -1077,7 +1081,7 @@
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
<string name="ringtone_default_with_actual" msgid="1767304850491060581">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
+ <string name="ringtone_silent" msgid="7937634392408977062">"Aucun(e)"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
<string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons de l\'alarme"</string>
<string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notification"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB en mode MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Appuyez ici pour plus d\'options."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non compatible"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Appuyer pour afficher plus d\'informations"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Accessoire audio analogique détecté"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"L\'appareil connecté n\'est pas compatible avec ce téléphone. Appuyez ici pour en savoir plus."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Appuyez ici pour désactiver le débogage USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index fc4e132..fbea639 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"A rede de telefonía móbil non ofrece o servizo na túa localización temporalmente"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Non se pode conectar coa rede"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para mellorar a recepción, proba a cambiar o tipo seleccionado en Configuración > Rede e Internet > Redes de telefonía móbil > Tipo de rede preferido."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Desvío de chamadas"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de devolución de chamadas de emerxencia"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de datos móbiles"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensaxes SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensaxes de correo de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Chamadas por wifi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro solicítalle ao operador que configure este servizo. Despois, activa de novo as chamadas por wifi en Configuración. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Rexístrate co teu operador"</item>
+ <item msgid="7472393097168811593">"Rexístrate co teu operador (código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -181,7 +186,7 @@
<string name="silent_mode" msgid="7167703389802618663">"Modo de silencio"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"Activar a conexión sen fíos"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"Desactivar a conexión sen fíos"</string>
- <string name="screen_lock" msgid="799094655496098153">"Bloqueo da pantalla"</string>
+ <string name="screen_lock" msgid="799094655496098153">"Bloqueo de pantalla"</string>
<string name="power_off" msgid="4266614107412865048">"Apagar"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Timbre desactivado"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Timbre en vibración"</string>
@@ -205,7 +210,7 @@
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opcións de tableta"</string>
<string name="global_actions" product="tv" msgid="7240386462508182976">"Opcións da televisión"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"Opcións de teléfono"</string>
- <string name="global_action_lock" msgid="2844945191792119712">"Bloqueo da pantalla"</string>
+ <string name="global_action_lock" msgid="2844945191792119712">"Bloqueo de pantalla"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Apagar"</string>
<string name="global_action_emergency" msgid="7112311161137421166">"Emerxencias"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nova"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Seguranza"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver máis opcións."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"O accesorio de audio non é compatible"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca para obter máis información"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Detectouse un accesorio de audio analóxico"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo conectado non é compatible con este teléfono. Toca para obter máis información."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para desactivar a depuración de erros de USB."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración de USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartindo informe de erros..."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 10f6658..f03cc9d 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"તમારા સ્થળે મોબાઇલ નેટવર્ક દ્વારા અસ્થાયીરૂપે ઑફર કરવામાં આવતી નથી"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"નેટવર્ક પર પહોંચી શકાતું નથી"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"રિસેપ્શનને બહેતર બનાવવા માટે, સેટિંગ્સ > નેટવર્ક અને ઇન્ટરનેટ > મોબાઇલ નેટવર્ક > પસંદગીના નેટવર્ક પ્રકાર પર પસંદ કરેલ પ્રકાર બદલવાનો પ્રયાસ કરો."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ચેતવણીઓ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"કૉલ ફૉર્વર્ડિંગ"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"કટોકટી કૉલબૅક મોડ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"મોબાઇલ ડેટા ચેતવણીઓ"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS સંદેશા"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"વૉઇસમેઇલ સંદેશા"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi કૉલિંગ"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલા તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
+ <item msgid="7472393097168811593">"તમારા કૅરિઅર સાથે નોંધણી કરો (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"વૉઇસ સહાય"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"હવે લૉક કરો"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"નવું નોટિફિકેશન"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"વર્ચ્યુઅલ કીબોર્ડ"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ભૌતિક કીબોર્ડ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"સુરક્ષા"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI માટે USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ઍક્સેસરીથી કનેક્ટ થયાં"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ઑડિયો ઍક્સેસરી સમર્થિત નથી"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"વધુ માહિતી માટે ટૅપ કરો"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"એનાલોગ ઑડિઓ ઍક્સેસરી મળી"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"જોડેલ ઉપકરણ આ ફોન સાથે સુસંગત નથી. વધુ જાણવા માટે ટૅપ કરો."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ડીબગિંગ અક્ષમ કરવા માટે ટૅપ કરો."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"બગ રિપોર્ટ શેર કરી રહ્યાં છે…"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index b34c20c..2ee48bf 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"आपके स्थान के मोबाइल नेटवर्क की ओर से इस समय ऑफ़र नहीं किया जा रहा है"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्क तक नहीं पहुंच पा रहे हैं"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्शन बेहतर करने के लिए, सेटिंग > नेटवर्क और इंटरनेट > मोबाइल नेटवर्क > पसंदीदा नेटवर्क प्रकार पर जाकर, चुना गया प्रकार बदलकर देखें."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"सूचनाएं"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल अग्रेषण"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपातकालीन कॉलबैक मोड"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटा सूचनाएं"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"वॉइसमेल संदेश"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"वाई-फ़ाई कॉलिंग"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट अप करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को दोबारा चालू करें. (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"अपने वाहक के साथ पंजीकृत करें"</item>
+ <item msgid="7472393097168811593">"अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से पंजीकृत करें (गड़बड़ी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"वॉइस सहायक"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"नया नोटिफ़िकेशन"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"वर्चुअल कीबोर्ड"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"भौतिक कीबोर्ड"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षा"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI के लिए USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्ट किया गया"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"अधिक विकल्पों के लिए टैप करें."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ऑडियो एक्सेसरी इस पर काम नहीं करती है"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"अधिक जानकारी के लिए टैप करें"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"एनालॉग ऑडियो एक्सेसरी का पता चला"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"अटैच किया गया डिवाइस इस फ़ोन से संगत नहीं है. अधिक जानने के लिए टैप करें."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करना अक्षम करने के लिए टैप करें."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f333c27..2f2d5933 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -81,10 +81,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutačno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Pristup mreži nije moguć"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Za bolji prijem pokušajte promijeniti vrstu odabranu u odjeljku Postavke > Mreža i internet > Mobilne mreže > Preferirana vrsta mreže."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmjeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način hitnog povratnog poziva"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozorenja o mobilnim podacima"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS poruke"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi pozivi"</string>
@@ -119,7 +124,7 @@
<item msgid="3910386316304772394">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama. (Kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrirajte se kod mobilnog operatera"</item>
+ <item msgid="7472393097168811593">"Registrirajte se kod mobilnog operatera (kôd pogreške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj sada"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nova obavijest"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtualna tipkovnica"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizička tipkovnica"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sigurnost"</string>
@@ -1198,8 +1202,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Spojen na USB pribor"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audiododatak nije podržan"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Otkriven je analogni audiododatak"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da biste saznali više."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka USB-om"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje pogrešaka putem USB-a."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
@@ -1638,7 +1642,7 @@
<string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao administrator"</string>
<string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao administrator"</string>
<string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao administrator"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, lokacijske usluge i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio podatkovni promet, Ušteda podataka onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f188cc8..25c859c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Az Ön tartózkodási helyén ideiglenesen nem áll rendelkezésre a mobilhálózaton"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"A hálózat nem érhető el"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"A vétel javítása érdekében próbálja módosítani a kiválasztott hálózattípust a Beállítások > Hálózat és internet > Mobilhálózatok > Preferált hálózattípus menüpontban."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Értesítések"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Hívásátirányítás"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Sürgősségi visszahívás mód"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobiladat-forgalommal kapcsolatos értesítések"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-ek"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Hangpostaüzenetek"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-hívás"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Ha Wi-Fi-hálózaton szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután kapcsolja be újra a Wi-Fi-hívást a Beállításokban. (Hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Regisztráljon a szolgáltatójánál"</item>
+ <item msgid="7472393097168811593">"Regisztráljon a szolgáltatójánál (hibakód: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Hangsegéd"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Új értesítés"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuális billentyűzet"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizikai billentyűzet"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Biztonság"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-hez"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Csatlakoztatva egy USB-kiegészítőhöz"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Koppintson a további beállítások megjelenítéséhez."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ez az audiotartozék nem támogatott"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Koppintson, ha további információra van szüksége"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analóg audiotartozék észlelve"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"A csatlakoztatott eszköz nem kompatibilis ezzel a telefonnal. További információért koppintson ide."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Koppintson az USB fejlesztő mód kikapcsolásához."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 083566d..0d333b1 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Ձեր գտնվելու վայրում ծառայությունը ժամանակավորապես չի տրամադրվում բջջային ցանցի կողմից"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ցանցն անհասանելի է"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ազդանշանի ընդունման որակը բարելավելու համար փոխեք ցանցի տեսակը՝ անցնելով Համակարգ > Ցանց և ինտերնետ > Բջջային ցանցեր > Ցանկալի ցանցի տեսակը։"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Ծանուցումներ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Զանգի վերահասցեավորում"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Շտապ հետկանչի ռեժիմ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Բջջային տվյալների ծանուցումներ"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS հաղորդագրություններ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Ձայնային փոստի հաղորդագրություններ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Զանգեր Wi-Fi-ի միջոցով"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ այս ծառայությունը կարգավորելու համար: Այնուհետև նորից միացրեք «Զանգեր Wi-Fi-ի միջոցով» ընտրանքը Կարգավորումներից: (Սխալի կոդ՝ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Գրանցվեք օպերատորի մոտ"</item>
+ <item msgid="7472393097168811593">"Գրանցվեք ձեր օպերատորի միջոցով (Սխալի կոդ` <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Կողպել հիմա"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Նոր ծանուցում"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Վիրտուալ ստեղնաշար"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Ֆիզիկական ստեղնաշար"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Անվտանգություն"</string>
@@ -264,7 +268,7 @@
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"օգտագործել օրացույցը"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ուղարկել և դիտել SMS-ները"</string>
- <string name="permgrouplab_storage" msgid="1971118770546336966">"Հիշողություն"</string>
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"Տարածք"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"օգտագործել լուսանկարները, մեդիա ֆայլերը և ձեր սարքում պահվող մյուս ֆայլերը"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Խոսափող"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ձայնագրել"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ի USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Աուդիո սարքը չի աջակցվում"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Հպեք՝ լրացուցիչ տեղեկություններ ստանալու համար"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Հայտնաբերված է անալոգային աուդիո լրասարք"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Միացված սարքը համատեղելի չէ այս հեռախոսի հետ: Հպեք` ավելին իմանալու համար:"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Հպեք՝ USB վրիպազերծումն անջատելու համար:"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e8474c0..edf1147 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Untuk sementara tidak ditawarkan oleh jaringan seluler di lokasi Anda"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat menjangkau jaringan"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Untuk menyempurnakan penerimaan sinyal, coba ubah jenis yang dipilih di Setelan > Jaringan & Internet > Jaringan seluler > Jenis jaringan pilihan."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Panggilan Wi‑Fi aktif"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Panggilan darurat memerlukan jaringan seluler."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Notifikasi"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Penerusan panggilan"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode panggilan balik darurat"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Notifikasi data seluler"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status data seluler"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Pesan SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Notifikasi pesan suara"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Panggilan Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Untuk menelepon dan mengirim pesan melalui Wi-Fi, tanyalah ke operator Anda terlebih dahulu untuk menyiapkan layanan ini. Kemudian, aktifkan kembali panggilan Wi-Fi dari Setelan. (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Harap daftarkan ke operator"</item>
+ <item msgid="7472393097168811593">"Daftarkan ke operator (Kode error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notifikasi baru"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Keyboard virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Keyboard fisik"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Keamanan"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Ketuk untuk opsi lainnya."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori audio tidak didukung"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap untuk info selengkapnya"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aksesori audio analog terdeteksi"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Perangkat yang terpasang tidak kompatibel dengan ponsel ini. Tap untuk mempelajari lebih lanjut."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ketuk untuk menonaktifkan debug USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index a41c41e..45cdc57 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Ekki í boði á farsímakerfinu á þínum stað eins og er"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ekki næst samband við símkerfi"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Reyndu að breyta valinni gerð í Stillingar > Netkerfi og internet > Farsímakerfi > Valin símkerfistegund til að bæta móttökuskilyrðin."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Tilkynningar"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Símtalsflutningur"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Stilling fyrir svarhringingu neyðarsímtala"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Tilkynningar fyrir farsímagögn"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-skilaboð"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Talhólfsskilaboð"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi símtöl"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum. (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Skráðu þig hjá símafyrirtækinu"</item>
+ <item msgid="7472393097168811593">"Skráðu þig hjá símafyrirtækinu (Villukóði: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Raddaðstoð"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Læsa núna"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ný tilkynning"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Sýndarlyklaborð"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Vélbúnaðarlyklaborð"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Öryggi"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB fyrir MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tengt við USB-aukabúnað"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Ýttu til að sjá fleiri valkosti."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Hljóðaukabúnaður er ekki studdur"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ýttu til að fá frekari upplýsingar"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Hliðrænn hljóðaukabúnaður greindist"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Tengda tækið er ekki samhæft við þennan síma. Ýttu til að fá frekari upplýsingar."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ýttu til að slökkva á USB-villuleit."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deilir villutilkynningu..."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0c0abf6..2d71456 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Servizio temporaneamente non offerto dalla rete mobile nella tua località"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossibile raggiungere la rete"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Per migliorare la ricezione, prova a modificare il tipo selezionato in Impostazioni > Rete e Internet > Reti mobili > Tipo di rete preferito."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Avvisi"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Deviazione chiamate"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modalità di richiamata di emergenza"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Avvisi relativi ai dati mobili"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Messaggi vocali"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Chiamate Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, chiedi prima al tuo operatore di impostare questo servizio. Dopodiché, attiva di nuovo la funzione Chiamate Wi-Fi nelle impostazioni. (Codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrati con il tuo operatore"</item>
+ <item msgid="7472393097168811593">"Registra con il tuo operatore (codice di errore: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Blocca ora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nuova notifica"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastiera virtuale"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastiera fisica"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sicurezza"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per la modalità MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Collegato a un accessorio USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tocca per altre opzioni."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessorio audio non supportato"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tocca per ulteriori informazioni"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Accessorio audio analogico rilevato"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Il dispositivo collegato non è compatibile con questo telefono. Tocca per avere ulteriori informazioni."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tocca per disattivare il debug USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0df22ea..2f62390 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"הרשת הסלולרית במיקום הזה חסמה את השירות באופן זמני"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"לא ניתן להתחבר לרשת"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"כדי לשפר את הקליטה, כדאי לנסות לשנות את סוג הרשת ב\'הגדרות\' > \'רשת ואינטרנט\' > \'רשתות סלולריות\' > \'סוג רשת מועדף\'."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"התראות"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"העברת שיחות"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"מצב \'התקשרות חזרה בחירום\'"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"התראות לגבי חבילת הגלישה"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"הודעות SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"הודעות קוליות"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"שיחות Wi-Fi"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'. (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"הירשם אצל הספק"</item>
+ <item msgid="7472393097168811593">"יש להירשם אצל הספק (קוד שגיאה: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"הודעה חדשה"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"מקלדת וירטואלית"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"מקלדת פיזית"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"אבטחה"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB ל-MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"מחובר לאביזר USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"הקש לקבלת אפשרויות נוספות."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"אביזר אודיו אינו נתמך"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"הקש לקבלת מידע נוסף"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"המכשיר זיהה התקן אודיו אנלוגי"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ההתקן שחיברת לא תואם לטלפון הזה. הקש למידע נוסף."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"ניפוי באגים של USB מחובר"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"הקש כדי להשבית ניפוי באגים של USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"בחר להשבית ניפוי באגים ב-USB."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3919001..bf6b50e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"現在地のモバイル ネットワークでは一時的に提供されていません"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ネットワークにアクセスできません"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"受信状態を改善するには、[設定] > [ネットワークとインターネット] > [モバイル ネットワーク] > [優先ネットワーク タイプ] で選択したタイプを変更してみてください。"</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi 通話が有効な状態です"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"緊急通報にはモバイル ネットワークが必要です。"</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"電話の転送"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急通報待機モード"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"モバイルデータ通知"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"モバイルデータのステータス"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS メッセージ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ボイスメール メッセージ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 通話を再度 ON にしてください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"携帯通信会社に登録してください"</item>
+ <item msgid="7472393097168811593">"携帯通信会社に登録してください(エラーコード: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"音声アシスト"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"今すぐロック"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"新しい通知"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"仮想キーボード"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"物理キーボード"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"セキュリティ"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"タップしてその他のオプションを表示します。"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"オーディオ アクセサリがサポートされていません"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"タップして詳細をご確認ください"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"アナログのオーディオ アクセサリを検出"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"接続したデバイスはこのスマートフォンと互換性がありません。タップすると、詳細を確認できます。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"タップして USB デバッグを無効にします。"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6c75ef3..f03d503 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"დროებით არ არის შემოთავაზებული მობილური ქსელის მიერ თქვენს მდებარეობაზე"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ქსელთან დაკავშირება ვერ ხერხდება"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"მიღების გასაუმჯობესებლად ცადეთ არჩეული ტიპის შეცვლა აქ: პარამეტრები > ქსელი და ინტერნეტი > მობილური ქსელები > ქსელის სასურველი ტიპი."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"აქტიურია Wi‑Fi დარეკვა"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"გადაუდებელი ზარები საჭიროებს მობილურ ქსელს."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"გაფრთხილებები"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ზარის გადამისამართება"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"გადაუდებელი გადმორეკვის რეჟიმი"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"მობილური ინტერნეტის შეტყობინებები"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"მობილური ინტერნეტის სტატუსი"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS შეტყობინებები"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ხმოვანი ფოსტის შეტყობინებები"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ კი ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან. (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
+ <item msgid="7472393097168811593">"თქვენს ოპერატორთან რეგისტრირება (შეცდომის კოდი: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ახლა ჩაკეტვა"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"ახალი შეტყობინება"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ვირტუალური კლავიატურა"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ფიზიკური კლავიატურა"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"უსაფრთხოება"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-სთვის"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"შეეხეთ დამატებითი ვარიანტების სანახავად."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"აუდიო აქსესუარი მხარდაუჭერელია"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"შეეხეთ დამატებითი ინფორმაციისთვის"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"აღმოჩენილია ანალოგური აუდიო აქსესუარი"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"მიერთებული მოწყობილობა არაა თავსებადი ამ ტელეფონთან. მეტის გასაგებად, შეეხეთ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"შეეხეთ USB-გამართვის გასათიშად."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 54a4b2f..9b53f18 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Орналасқан аймағыңызда мобильдік желі уақытша ұсынбады"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Желіге қосылу мүмкін емес"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Қабылдауды жақсарту үшін \"Параметрлер > Желі және интернет > Мобильді желілер және қалаулы желі түрі\" тармағынан түрді өзгертіп көріңіз."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Дабылдар"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Қоңырауды басқа нөмірге бағыттау"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Шұғыл кері қоңырау шалу режимі"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Мобильдік деректер дабылдары"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS хабарлары"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Дауыстық пошта хабарлары"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi қоңыраулары"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi арқылы қоңырау шалу немесе хабарлар жіберу үшін, алдымен операторыңыздан құрылғыны реттеуді сұраңыз. Содан кейін \"Параметрлер\" бөлімінен Wi-Fi қоңырауларын қайта қосыңыз. (Қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Жабдықтаушыңыз арқылы тіркелу"</item>
+ <item msgid="7472393097168811593">"Оператор арқылы тіркеліңіз (қате коды: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Қазір бекіту"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңа хабарландыру"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалды пернетақта"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Қатты пернетақта"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Қауіпсіздік"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI режиміне арналған USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB жабдығына қосылған"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Қосымша опциялар үшін түртіңіз."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио аксессуарға қолдау көрсетілмейді"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Қосымша ақпарат алу үшін түртіңіз"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогтық аудиожабдық анықталды"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Жалғанған құрылғы бұл телефонмен үйлесімсіз. Қосымша ақпарат алу үшін түртіңіз."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB түзетуін өшіру үшін түртіңіз."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Қате туралы есеп бөлісілуде…"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e2592fb..bf58d05 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"មិនបានផ្តល់ជូនដោយបណ្តាញចល័តនៅទីកន្លែងរបស់អ្នកជាបណ្តោះអាសន្ន"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"មិនអាចភ្ជាប់ទៅបណ្តាញបានទេ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ដើម្បីធ្វើឲ្យការទទួលរលកសញ្ញាប្រសើរជាងមុន សូមសាកល្បងប្តូរប្រភេទដែលបានជ្រើសរើសនៅ ការកំណត់ > បណ្តាញ និងអ៊ីនធឺណិត > បណ្តាញទូរសព្ទចល័ត > ប្រភេទបណ្តាញដែលចង់ប្រើ។"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ការជូនដំណឹង"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ការបញ្ជូនការហៅទូរសព្ទបន្ត"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"មុខងារហៅត្រឡប់វិញបន្ទាន់"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ការជូនដំណឹងអំពីទិន្នន័យទូរសព្ទចល័ត"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"សារ SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"សារជាសំឡេង"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"ការហៅទូរសព្ទតាម Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"ដើម្បីហៅទូរសព្ទ និងផ្ញើសារតាម Wi-Fi អ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នកដំឡើងសេវាកម្មនេះជាមុនសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតនៅក្នុងការកំណត់។ (លេខកូដបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+ <item msgid="7472393097168811593">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនបម្រើសេវាទូរសព្ទរបស់អ្នក (លេខកូដមានបញ្ហា៖ <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ជំនួយសម្លេង"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោឥឡូវនេះ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"ការជូនដំណឹងថ្មី"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ក្ដារចុចនិម្មិត"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ក្ដារចុចរូបវន្ត"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"សុវត្ថិភាព"</string>
@@ -1178,8 +1182,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB សម្រាប់ MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"បានភ្ជាប់ឧបករណ៍យូអេសប៊ី"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"មិនស្គាល់គ្រឿងបរិក្ខារសំឡេងទេ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ចុចដើម្បីទទួលព័ត៌មានបន្ថែម"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"បានរកឃើញគ្រឿងបរិក្ខារសំឡេងអាណាឡូក"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ឧបករណ៍ដែលភ្ជាប់មកជាមួយមិនត្រូវគ្នាជាមួយទូរសព្ទនេះទេ។ ចុចដើម្បីស្វែងយល់បន្ថែម។"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"បានភ្ជាប់ការកែកំហុសយូអេសប៊ី"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុសយូអេសប៊ី"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស ដើម្បីបិទការកែកំហុសយូអេសប៊ី។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 0f21aef..9e20a58 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"ತಾತ್ಕಾಲಿಕವಾಗಿ ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ನಿಂದ ನಿಮ್ಮ ಸ್ಥಳದಲ್ಲಿ ಒದಗಿಸುತ್ತಿಲ್ಲ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ನೆಟ್ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕ ಪಡೆಯುವುದನ್ನು ಸುಧಾರಿಸಲು, ಆಯ್ಕೆ ಮಾಡಿರುವ ವಿಧವನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳು > ನೆಟ್ವರ್ಕ್ ಮತ್ತು ಇಂಟರ್ನೆಟ್ > ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ಗಳು > ಆದ್ಯತೆಯ ನೆಟ್ವರ್ಕ್ ವಿಧದಲ್ಲಿ ಬದಲಿಸಿ ನೋಡಿ."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ಎಚ್ಚರಿಕೆಗಳು"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ಕರೆ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆ"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ತುರ್ತು ಕಾಲ್ಬ್ಯಾಕ್ ಮೋಡ್"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ಮೊಬೈಲ್ ಡೇಟಾ ಎಚ್ಚರಿಕೆಗಳು"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"ಎಸ್ಎಂಎಸ್ ಸಂದೇಶಗಳು"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ಧ್ವನಿಮೇಲ್ ಸಂದೇಶಗಳು"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"ವೈ-ಫೈ ಮೂಲಕ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಈ ಸೇವೆಯನ್ನು ಹೊಂದಿಸಲು ಮೊದಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ಆ ನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ವೈ-ಫೈ ಕರೆಮಾಡುವಿಕೆಯನ್ನು ಅನ್ನು ಆನ್ ಮಾಡಿ. (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
+ <item msgid="7472393097168811593">"ನಿಮ್ಮ ವಾಹಕದ ಜೊತೆಗೆ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ (ದೋಷ ಕೋಡ್: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -214,7 +219,7 @@
<string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ"</string>
<string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸಿ. ಇದು ವರದಿಯ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು, ಸಮಸ್ಯೆ ಕುರಿತು ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಮತ್ತು ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ವರದಿ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುವಂತಹ ಕೆಲವು ಕಡಿಮೆ ಬಳಸಲಾದ ವಿಭಾಗಗಳನ್ನು ತ್ಯಜಿಸಬಹುದು."</string>
<string name="bugreport_option_full_title" msgid="6354382025840076439">"ಪೂರ್ಣ ವರದಿ"</string>
- <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ನಿಮ್ಮ ಸಾಧನವು ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲದಿರುವಾಗ ಅಥವಾ ತುಂಬಾ ನಿಧಾನವಾಗಿರುವಾಗ ಕನಿಷ್ಟ ಹಸ್ತಕ್ಷೇಪಕ್ಕಾಗಿ ಅಥವಾ ನಿಮಗೆ ಎಲ್ಲಾ ವಿಭಾಗಗಳೂ ಅಗತ್ಯವಿರುವಾಗ ಈ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ. ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಅಥವಾ ಹೆಚ್ಚುವರಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string>
+ <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ನಿಮ್ಮ ಸಾಧನವು ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲದಿರುವಾಗ ಅಥವಾ ತುಂಬಾ ನಿಧಾನವಾಗಿರುವಾಗ ಕನಿಷ್ಠ ಹಸ್ತಕ್ಷೇಪಕ್ಕಾಗಿ ಅಥವಾ ನಿಮಗೆ ಎಲ್ಲಾ ವಿಭಾಗಗಳೂ ಅಗತ್ಯವಿರುವಾಗ ಈ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ. ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಅಥವಾ ಹೆಚ್ಚುವರಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
<item quantity="one">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
<item quantity="other">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ಈಗ ಲಾಕ್ ಮಾಡಿ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"ಹೊಸ ಅಧಿಸೂಚನೆ"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ವರ್ಚುಯಲ್ ಕೀಬೋರ್ಡ್"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ಭದ್ರತೆ"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ಗೆ USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ಪರಿಕರಕ್ಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ಆಡಿಯೋ ಪರಿಕರಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ಅನ್ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚುವುದೇ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
@@ -1585,7 +1588,7 @@
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ಹೊಸ ಪಿನ್ ದೃಢೀಕರಿಸಿ"</string>
<string name="restr_pin_create_pin" msgid="8017600000263450337">"ನಿರ್ಬಂಧಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಪಿನ್ ರಚಿಸಿ"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ಪಿನ್ ಗಳು ಹೊಂದಿಕೆಯಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ಪಿನ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಟ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string>
+ <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ಪಿನ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಠ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
<item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</item>
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 41be35b..1a0aef2 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"현재 위치에서 모바일 네트워크가 서비스 제공을 일시적으로 중단했습니다."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"네트워크에 연결할 수 없습니다."</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"수신 상태를 개선하려면 설정 > 네트워크 및 인터넷 > 모바일 네트워크 > 기본 네트워크 유형에서 선택된 유형을 변경해 보세요."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"알림"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"착신전환"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"긴급 콜백 모드"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"모바일 데이터 알림"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS 메시지"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"음성사서함 메시지"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 통화"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 서비스를 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다. (오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"이동통신사에 등록"</item>
+ <item msgid="7472393097168811593">"이동통신사에 등록하세요(오류 코드: <xliff:g id="CODE">%1$s</xliff:g>)."</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"지금 잠그기"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"새 알림"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"가상 키보드"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"물리적 키보드"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"보안"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI용 USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"옵션을 더 보려면 탭하세요."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"지원되지 않는 오디오 액세서리"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"자세한 내용은 탭하여 확인하세요."</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"아날로그 오디오 액세서리가 감지됨"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"연결된 기기가 이 휴대전화와 호환되지 않습니다. 자세히 알아보려면 탭하세요."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB 디버깅을 사용하지 않으려면 탭하세요."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 051b01e..a48b6bc 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Өзгөчө кырдаалдагы кызматтар сиз жайгашкан жердеги мобилдик тармак тарабынан убактылуу бөгөттөлгөн"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Тармакка туташпай жатат"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Кабыл алуу мүмкүнчүлүгүн жакшыртуу үчүн Жөндөөлөр > Тармак жана Интернет > Мобилдик тармактар > Тандалган тармак бөлүмүнөн тармактын түрүн өзгөртүп көрүңүз."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi аркылуу чалуу жүрүп жатат"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Шашылыш чалуу үчүн мобилдик тармак талап кылынат."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Эскертүүлөр"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Чалууну башка номерге багыттоо"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Шашылыш кайра чалуу режими"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Мобилдик Интернеттин эскертүүлөрү"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Мобилдик Интернеттин абалы"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS билдирүүлөрү"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Үн почтасынын билдирүүлөрү"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi аркылуу чалуу"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз. (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Операторуңузга катталыңыз"</item>
+ <item msgid="7472393097168811593">"Операторуңузга катталыңыз (Ката коду: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңы эскертме"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалдык баскычтоп"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Аппараттык баскычтоп"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Коопсуздук"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI үчүн USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB аксессуарга байланышты"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио шайманы колдоого алынбайт"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогдук аудио жабдуу табылды"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Мүчүлштктрдү USB аркл оңдну өчр үчн тийп коюңуз."</string>
<!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9790dd2..6f8ddac 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"ເຄືອຂ່າຍຂອງທ່ານບໍ່ໄດ້ໃຫ້ບໍລິການຢູ່ສະຖານທີ່ນີ້ເປັນການຊົ່ວຄາວ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t reach network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ເພື່ອປັບປຸງການຮັບສັນຍານ, ໃຫ້ລອງປ່ຽນປະເພດທີ່ເລືອກໄວ້ຢູ່ທີ່ ການຕັ້ງຄ່າ > ເຄືອຂ່າຍ ແລະ ອິນເຕີເນັດ > ເຄືອຂ່າຍມືຖື > ປະເພດເຄືອຂ່າຍທີ່ຕ້ອງການ."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"ການໂທ Wi‑Fi ເຮັດວຽກຢູ່"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"ການໂທສຸກເສີນຕ້ອງໃຊ້ການເຊື່ອມຕໍ່ເຄືອຂ່າຍ."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ການເຕືອນ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ການໂອນສາຍ"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ໂໝດໂທກັບສຸກເສີນ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ການແຈ້ງເຕືອນອິນເຕີເນັດມືຖື"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"ສະຖານະອິນເຕີເນັດມືຖື"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"ຂໍ້ຄວາມ SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ຂໍ້ຄວາມສຽງ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"ການໂທ Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງໃຫ້ຜູ້ໃຫ້ບໍລິການຂອງທ່ານຕັ້ງບໍລິການນີ້. ຈາກນັ້ນເປີດໃຊ້ການໂທ Wi-Fi ອີກຄັ້ງຈາກການຕັ້ງຄ່າ. (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ລົງທະບຽນກັບຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ"</item>
+ <item msgid="7472393097168811593">"ລົງທະບຽນກັບຜູ້ໃຫ້ບໍລິການຂອງທ່ານ (ລະຫັດຂໍ້ຜິດພາດ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ຊ່ວຍເຫຼືອທາງສຽງ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກດຽວນີ້"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"ການແຈ້ງເຕືອນໃໝ່"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ແປ້ນພິມສະເໝືອນ"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ແປ້ນພິມພາຍນອກ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ຄວາມປອດໄພ"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB ສຳລັບ MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ບໍ່ຮອງຮັບອຸປະກອນເສີມສຽງ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນ"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ກວດພົບອຸປະກອນເສີມສຽງ"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ອຸປະກອນທີ່ເຊື່ອມຕໍ່ນັ້ນບໍ່ສາມາດໃຊ້ຮ່ວມກັບໂທລະສັບນີ້ໄດ້. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"ແຕະເພື່ອປິດການດີບັກຜ່ານ USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 35cb9b9..d2a8227 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Laikinai nesiūloma mobiliojo ryšio tinkle jūsų vietovėje"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepavyko pasiekti tinklo"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Kad pagerintumėte ryšį, pabandykite pakeisti tipą, pasirinktą skiltyje „Nustatymai“ > „Tinklas ir internetas“ > „Mobiliojo ryšio tinklai“ > „Pageidaujamas tinklo tipas“."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Įspėjimai"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Skambučio peradresavimas"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Atskambinimo pagalbos numeriu režimas"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobiliojo ryšio duomenų įspėjimai"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS pranešimai"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Balso pašto pranešimai"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"„Wi-Fi“ skambinimas"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą skiltyje „Nustatymai“. (Klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Užregistruokite pas operatorių"</item>
+ <item msgid="7472393097168811593">"Užregistruokite pas operatorių (klaidos kodas: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Užrakinti dabar"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Naujas pranešimas"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtualioji klaviatūra"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizinė klaviatūra"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sauga"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB (MIDI)"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Prijungta prie USB priedo"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Garso įrašo priedas nepalaikomas"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aptiktas analoginis garso priedas"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Prijungtas įrenginys nesuderinamas su šiuo telefonu. Palieskite, kad sužinotumėte daugiau."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Palieskite, kad išjungtumėte USB derinimą."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 2c54905..2d4a808 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -81,10 +81,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Pagaidām netiek piedāvāts mobilajā tīklā jūsu atrašanās vietā"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nevar sasniegt tīklu"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Lai uzlabotu uztveršanu, mainiet atlasīto veidu sadaļā Iestatījumi > Tīkls un internets > Mobilie tīkli > Ieteicamais tīkla veids."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Brīdinājumi"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Zvanu pāradresācija"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Ārkārtas atzvana režīms"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobilo datu brīdinājumi"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Īsziņas"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Balss pasta ziņojumi"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi zvani"</string>
@@ -119,7 +124,7 @@
<item msgid="3910386316304772394">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus. (Kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
+ <item msgid="7472393097168811593">"Reģistrējieties pie sava mobilo sakaru operatora (kļūdas kods: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloķēt tūlīt"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Jauns paziņojums"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuālā tastatūra"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziskā tastatūra"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Drošība"</string>
@@ -1198,8 +1202,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB savienojums MIDI režīmā"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Pieskarieties, lai skatītu citas iespējas."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio piederums netiek atbalstīts"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Pieskarieties, lai uzzinātu vairāk"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Konstatēts analogs audio piederums"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pievienotā ierīce nav saderīga ar šo tālruni. Pieskarieties, lai uzzinātu vairāk."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
diff --git a/core/res/res/values-mcc302-mnc370-en-rXC/strings.xml b/core/res/res/values-mcc302-mnc370-en-rXC/strings.xml
new file mode 100644
index 0000000..5328d1e
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370-en-rXC/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+** 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wfcSpnFormats">
+ <item msgid="5022384999749536798">"%s"</item>
+ <item msgid="8117276330682171665">"%s Wi-Fi"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720-en-rXC/strings.xml b/core/res/res/values-mcc302-mnc720-en-rXC/strings.xml
new file mode 100644
index 0000000..5d14078
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720-en-rXC/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+** 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wfcSpnFormats">
+ <item msgid="2776657861851140021">"%s"</item>
+ <item msgid="5094669985484060934">"%s Wi-Fi"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-af/strings.xml b/core/res/res/values-mcc310-mnc260-af/strings.xml
deleted file mode 100644
index ee051c5..0000000
--- a/core/res/res/values-mcc310-mnc260-af/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registreer by jou diensverskaffer"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-oproep"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-am/strings.xml b/core/res/res/values-mcc310-mnc260-am/strings.xml
deleted file mode 100644
index 74f711a..0000000
--- a/core/res/res/values-mcc310-mnc260-am/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"የ%s Wi-Fi ጥሪ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ar/strings.xml b/core/res/res/values-mcc310-mnc260-ar/strings.xml
deleted file mode 100644
index 5a84295..0000000
--- a/core/res/res/values-mcc310-mnc260-ar/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"التسجيل لدى مشغّل شبكة الجوّال"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s جارٍ الاتصال عبر Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-az/strings.xml b/core/res/res/values-mcc310-mnc260-az/strings.xml
deleted file mode 100644
index 32d21c5..0000000
--- a/core/res/res/values-mcc310-mnc260-az/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Operatorla qeydiyyatdan keçin"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Zəngi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
deleted file mode 100644
index 6750940..0000000
--- a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrujte se kod mobilnog operatera"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-be/strings.xml b/core/res/res/values-mcc310-mnc260-be/strings.xml
deleted file mode 100644
index 497366b..0000000
--- a/core/res/res/values-mcc310-mnc260-be/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Зарэгіструйцеся ў свайго аператара"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-тэлефанія %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bg/strings.xml b/core/res/res/values-mcc310-mnc260-bg/strings.xml
deleted file mode 100644
index a671120..0000000
--- a/core/res/res/values-mcc310-mnc260-bg/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Регистриране с оператора ви"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s – обаждания през Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bn/strings.xml b/core/res/res/values-mcc310-mnc260-bn/strings.xml
deleted file mode 100644
index 67955d5..0000000
--- a/core/res/res/values-mcc310-mnc260-bn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi কলিং"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bs/strings.xml b/core/res/res/values-mcc310-mnc260-bs/strings.xml
deleted file mode 100644
index 64e4862..0000000
--- a/core/res/res/values-mcc310-mnc260-bs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrirajte se kod svog operatera"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ca/strings.xml b/core/res/res/values-mcc310-mnc260-ca/strings.xml
deleted file mode 100644
index 8ce8dc8..0000000
--- a/core/res/res/values-mcc310-mnc260-ca/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registra\'t amb el teu operador de telefonia mòbil"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Trucada de Wi-Fi de: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-cs/strings.xml b/core/res/res/values-mcc310-mnc260-cs/strings.xml
deleted file mode 100644
index 61ba268..0000000
--- a/core/res/res/values-mcc310-mnc260-cs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrace u operátora"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Volání přes Wi-Fi: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-da/strings.xml b/core/res/res/values-mcc310-mnc260-da/strings.xml
deleted file mode 100644
index 0c612e5..0000000
--- a/core/res/res/values-mcc310-mnc260-da/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrer dig hos dit mobilselskab"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-opkald"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-de/strings.xml b/core/res/res/values-mcc310-mnc260-de/strings.xml
deleted file mode 100644
index b9cbb48..0000000
--- a/core/res/res/values-mcc310-mnc260-de/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registriere dich bei deinem Mobilfunkanbieter."</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Anrufe über WLAN"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-el/strings.xml b/core/res/res/values-mcc310-mnc260-el/strings.xml
deleted file mode 100644
index b4cd123..0000000
--- a/core/res/res/values-mcc310-mnc260-el/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Κλήση Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Register with your operator"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Register with your operator"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Register with your operator"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
deleted file mode 100644
index 6398c02..0000000
--- a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Regístrate con tu proveedor."</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada por Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es/strings.xml b/core/res/res/values-mcc310-mnc260-es/strings.xml
deleted file mode 100644
index e959116..0000000
--- a/core/res/res/values-mcc310-mnc260-es/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Regístrate con tu operador"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-et/strings.xml b/core/res/res/values-mcc310-mnc260-et/strings.xml
deleted file mode 100644
index 2310130..0000000
--- a/core/res/res/values-mcc310-mnc260-et/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registreeruge operaatori juures"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WiFi kaudu helistamine"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-eu/strings.xml b/core/res/res/values-mcc310-mnc260-eu/strings.xml
deleted file mode 100644
index 8fb03d4..0000000
--- a/core/res/res/values-mcc310-mnc260-eu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Erregistratu operadorearekin"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi bidezko deiak"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fa/strings.xml b/core/res/res/values-mcc310-mnc260-fa/strings.xml
deleted file mode 100644
index 659a0dd..0000000
--- a/core/res/res/values-mcc310-mnc260-fa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتیتان درخواست کنید این سرویس را راهاندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ثبت نام با شرکت مخابراتی شما"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"تماس %s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fi/strings.xml b/core/res/res/values-mcc310-mnc260-fi/strings.xml
deleted file mode 100644
index 1eecb61..0000000
--- a/core/res/res/values-mcc310-mnc260-fi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Rekisteröidy operaattorisi asiakkaaksi."</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-puhelut: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
deleted file mode 100644
index c767039..0000000
--- a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Inscrivez-vous auprès de votre fournisseur de services"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr/strings.xml b/core/res/res/values-mcc310-mnc260-fr/strings.xml
deleted file mode 100644
index 1de93ca..0000000
--- a/core/res/res/values-mcc310-mnc260-fr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Inscrivez-vous auprès de votre opérateur."</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gl/strings.xml b/core/res/res/values-mcc310-mnc260-gl/strings.xml
deleted file mode 100644
index 2747ab3..0000000
--- a/core/res/res/values-mcc310-mnc260-gl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Rexístrate co teu operador"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas wifi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gu/strings.xml b/core/res/res/values-mcc310-mnc260-gu/strings.xml
deleted file mode 100644
index d02d5ad..0000000
--- a/core/res/res/values-mcc310-mnc260-gu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi કૉલિંગ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hi/strings.xml b/core/res/res/values-mcc310-mnc260-hi/strings.xml
deleted file mode 100644
index a19f51a..0000000
--- a/core/res/res/values-mcc310-mnc260-hi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"अपने वाहक के साथ पंजीकृत करें"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाई-फ़ाई कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hr/strings.xml b/core/res/res/values-mcc310-mnc260-hr/strings.xml
deleted file mode 100644
index dc48a1e..0000000
--- a/core/res/res/values-mcc310-mnc260-hr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrirajte se kod mobilnog operatera"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi pozivanje"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hu/strings.xml b/core/res/res/values-mcc310-mnc260-hu/strings.xml
deleted file mode 100644
index ef6a2fc..0000000
--- a/core/res/res/values-mcc310-mnc260-hu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Regisztráljon a szolgáltatójánál"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-hívás"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hy/strings.xml b/core/res/res/values-mcc310-mnc260-hy/strings.xml
deleted file mode 100644
index 0a37df2..0000000
--- a/core/res/res/values-mcc310-mnc260-hy/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Գրանցվեք օպերատորի մոտ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi զանգեր"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-in/strings.xml b/core/res/res/values-mcc310-mnc260-in/strings.xml
deleted file mode 100644
index 4da068e..0000000
--- a/core/res/res/values-mcc310-mnc260-in/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Harap daftarkan ke operator"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-is/strings.xml b/core/res/res/values-mcc310-mnc260-is/strings.xml
deleted file mode 100644
index 1fd14d4..0000000
--- a/core/res/res/values-mcc310-mnc260-is/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Skráðu þig hjá símafyrirtækinu"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi símtöl"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-it/strings.xml b/core/res/res/values-mcc310-mnc260-it/strings.xml
deleted file mode 100644
index 6a7dec5..0000000
--- a/core/res/res/values-mcc310-mnc260-it/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrati con il tuo operatore"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Chiamata Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-iw/strings.xml b/core/res/res/values-mcc310-mnc260-iw/strings.xml
deleted file mode 100644
index 1bcce94..0000000
--- a/core/res/res/values-mcc310-mnc260-iw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"הירשם אצל הספק"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"שיחות Wi-Fi של %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ja/strings.xml b/core/res/res/values-mcc310-mnc260-ja/strings.xml
deleted file mode 100644
index 05a333b..0000000
--- a/core/res/res/values-mcc310-mnc260-ja/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"携帯通信会社に登録してください"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi通話(%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ka/strings.xml b/core/res/res/values-mcc310-mnc260-ka/strings.xml
deleted file mode 100644
index dbb2822..0000000
--- a/core/res/res/values-mcc310-mnc260-ka/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s დარეკვა Wi-Fi-ს მეშვეობით"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kk/strings.xml b/core/res/res/values-mcc310-mnc260-kk/strings.xml
deleted file mode 100644
index 80eebfc..0000000
--- a/core/res/res/values-mcc310-mnc260-kk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Жабдықтаушыңыз арқылы тіркелу"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi арқылы қоңырау шалу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-km/strings.xml b/core/res/res/values-mcc310-mnc260-km/strings.xml
deleted file mode 100644
index e3cd1b2..0000000
--- a/core/res/res/values-mcc310-mnc260-km/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"ការហៅតាមរយៈ Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kn/strings.xml b/core/res/res/values-mcc310-mnc260-kn/strings.xml
deleted file mode 100644
index 0a9d58d..0000000
--- a/core/res/res/values-mcc310-mnc260-kn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಮತ್ತೆ Wi-Fi ಆನ್ ಮಾಡಿ."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ko/strings.xml b/core/res/res/values-mcc310-mnc260-ko/strings.xml
deleted file mode 100644
index 5581235..0000000
--- a/core/res/res/values-mcc310-mnc260-ko/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"이동통신사에 등록"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 통화"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ky/strings.xml b/core/res/res/values-mcc310-mnc260-ky/strings.xml
deleted file mode 100644
index 775542d..0000000
--- a/core/res/res/values-mcc310-mnc260-ky/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Операторуңузга катталыңыз"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Чалуу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lo/strings.xml b/core/res/res/values-mcc310-mnc260-lo/strings.xml
deleted file mode 100644
index 49f79016..0000000
--- a/core/res/res/values-mcc310-mnc260-lo/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"ເພື່ອໂທ ແລະສົ່ງຂໍ້ຄວາມຢູ່ເທິງ Wi-Fi, ກ່ອນອື່ນໝົດໃຫ້ຖ້າມຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ ເພື່ອຕັ້ງການບໍລິການນີ້. ຈາກນັ້ນເປີດການໂທ Wi-Fi ອີກຈາກການຕັ້ງຄ່າ."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ລົງທະບຽນກັບຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"ການໂທ %s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lt/strings.xml b/core/res/res/values-mcc310-mnc260-lt/strings.xml
deleted file mode 100644
index 4c3ebb7..0000000
--- a/core/res/res/values-mcc310-mnc260-lt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Užregistruokite pas operatorių"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"„%s“ „Wi-Fi“ skambinimas"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lv/strings.xml b/core/res/res/values-mcc310-mnc260-lv/strings.xml
deleted file mode 100644
index 23d8ca0..0000000
--- a/core/res/res/values-mcc310-mnc260-lv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi zvani"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mk/strings.xml b/core/res/res/values-mcc310-mnc260-mk/strings.xml
deleted file mode 100644
index 878b7af..0000000
--- a/core/res/res/values-mcc310-mnc260-mk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Регистрирајте се со операторот"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Повикување преку Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ml/strings.xml b/core/res/res/values-mcc310-mnc260-ml/strings.xml
deleted file mode 100644
index a94680d..0000000
--- a/core/res/res/values-mcc310-mnc260-ml/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s വൈഫൈ കോളിംഗ്"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mn/strings.xml b/core/res/res/values-mcc310-mnc260-mn/strings.xml
deleted file mode 100644
index 4c97e2e..0000000
--- a/core/res/res/values-mcc310-mnc260-mn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Операторт бүртгүүлэх"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Дуудлага"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mr/strings.xml b/core/res/res/values-mcc310-mnc260-mr/strings.xml
deleted file mode 100644
index 06eceff..0000000
--- a/core/res/res/values-mcc310-mnc260-mr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"आपल्या वाहकासह नोंदणी करा"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाय-फाय कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ms/strings.xml b/core/res/res/values-mcc310-mnc260-ms/strings.xml
deleted file mode 100644
index dafb3bd..0000000
--- a/core/res/res/values-mcc310-mnc260-ms/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Daftar dengan pembawa anda"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-my/strings.xml b/core/res/res/values-mcc310-mnc260-my/strings.xml
deleted file mode 100644
index 25ea191..0000000
--- a/core/res/res/values-mcc310-mnc260-my/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"ဝိုင်ဖိုင်သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်စေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် ဝိုင်ဖိုင် ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ဝိုင်ဖိုင် ခေါ်ဆိုမှု"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nb/strings.xml b/core/res/res/values-mcc310-mnc260-nb/strings.xml
deleted file mode 100644
index 9918996..0000000
--- a/core/res/res/values-mcc310-mnc260-nb/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrer deg hos operatøren din"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-anrop"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ne/strings.xml b/core/res/res/values-mcc310-mnc260-ne/strings.xml
deleted file mode 100644
index 6fb7b50..0000000
--- a/core/res/res/values-mcc310-mnc260-ne/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi कलिङ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
deleted file mode 100644
index ac4961c..0000000
--- a/core/res/res/values-mcc310-mnc260-nl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registreren bij je provider"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Bellen via wifi van %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pa/strings.xml b/core/res/res/values-mcc310-mnc260-pa/strings.xml
deleted file mode 100644
index 0026681..0000000
--- a/core/res/res/values-mcc310-mnc260-pa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pl/strings.xml b/core/res/res/values-mcc310-mnc260-pl/strings.xml
deleted file mode 100644
index b7f512d..0000000
--- a/core/res/res/values-mcc310-mnc260-pl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Zarejestruj u operatora"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Połączenia przez Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
deleted file mode 100644
index 18e3801..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registar-se junto do seu operador"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas por Wi-Fi da %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt/strings.xml b/core/res/res/values-mcc310-mnc260-pt/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ro/strings.xml b/core/res/res/values-mcc310-mnc260-ro/strings.xml
deleted file mode 100644
index 6b865a2..0000000
--- a/core/res/res/values-mcc310-mnc260-ro/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Înregistrați-vă la operatorul dvs."</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Apelare prin Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ru/strings.xml b/core/res/res/values-mcc310-mnc260-ru/strings.xml
deleted file mode 100644
index 829c477..0000000
--- a/core/res/res/values-mcc310-mnc260-ru/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Укажите оператора и зарегистрируйтесь"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Звонки по Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-si/strings.xml b/core/res/res/values-mcc310-mnc260-si/strings.xml
deleted file mode 100644
index de00901..0000000
--- a/core/res/res/values-mcc310-mnc260-si/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්රියාත්මක කරන්න."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi අමතමින්"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sk/strings.xml b/core/res/res/values-mcc310-mnc260-sk/strings.xml
deleted file mode 100644
index eb8b5f8..0000000
--- a/core/res/res/values-mcc310-mnc260-sk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrujte sa so svojím operátorom"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Volanie siete Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sl/strings.xml b/core/res/res/values-mcc310-mnc260-sl/strings.xml
deleted file mode 100644
index ae30c5a..0000000
--- a/core/res/res/values-mcc310-mnc260-sl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registracija pri operaterju"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Klicanje prek Wi-Fi-ja (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sq/strings.xml b/core/res/res/values-mcc310-mnc260-sq/strings.xml
deleted file mode 100644
index 84ac153..0000000
--- a/core/res/res/values-mcc310-mnc260-sq/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Regjistrohu me operatorin tënd celular"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Telefonatat me Wi-Fi nga %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sr/strings.xml b/core/res/res/values-mcc310-mnc260-sr/strings.xml
deleted file mode 100644
index 92c6f35..0000000
--- a/core/res/res/values-mcc310-mnc260-sr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Региструјте се код мобилног оператера"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi позивање преко оператера %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sv/strings.xml b/core/res/res/values-mcc310-mnc260-sv/strings.xml
deleted file mode 100644
index 632a2ce..0000000
--- a/core/res/res/values-mcc310-mnc260-sv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registrera dig hos operatören"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-samtal"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sw/strings.xml b/core/res/res/values-mcc310-mnc260-sw/strings.xml
deleted file mode 100644
index eecf6d2..0000000
--- a/core/res/res/values-mcc310-mnc260-sw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Jisajili na mtoa huduma wako"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Upigaji Simu kwa Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ta/strings.xml b/core/res/res/values-mcc310-mnc260-ta/strings.xml
deleted file mode 100644
index 144bc95..0000000
--- a/core/res/res/values-mcc310-mnc260-ta/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s வைஃபை அழைப்பு"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-te/strings.xml b/core/res/res/values-mcc310-mnc260-te/strings.xml
deleted file mode 100644
index ef94c4c..0000000
--- a/core/res/res/values-mcc310-mnc260-te/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fiలో కాల్లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్ను అడగండి. ఆపై సెట్టింగ్ల నుండి మళ్లీ Wi-Fi కాలింగ్ను ఆన్ చేయండి."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"మీ క్యారియర్తో నమోదు చేయండి"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi కాలింగ్"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-th/strings.xml b/core/res/res/values-mcc310-mnc260-th/strings.xml
deleted file mode 100644
index dd026cc..0000000
--- a/core/res/res/values-mcc310-mnc260-th/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"ลงทะเบียนกับผู้ให้บริการ"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"กำลังเรียก Wi-Fi ของ %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tl/strings.xml b/core/res/res/values-mcc310-mnc260-tl/strings.xml
deleted file mode 100644
index 5557835..0000000
--- a/core/res/res/values-mcc310-mnc260-tl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Magparehistro sa iyong carrier"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Pagtawag sa Pamamagitan ng Wi-Fi ng %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tr/strings.xml b/core/res/res/values-mcc310-mnc260-tr/strings.xml
deleted file mode 100644
index 7cfd9c1..0000000
--- a/core/res/res/values-mcc310-mnc260-tr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Operatörünüze kaydolun"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Kablosuz Çağrı"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uk/strings.xml b/core/res/res/values-mcc310-mnc260-uk/strings.xml
deleted file mode 100644
index 0c21309..0000000
--- a/core/res/res/values-mcc310-mnc260-uk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Зареєструйтеся в оператора"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Дзвінок через Wi-Fi від оператора %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ur/strings.xml b/core/res/res/values-mcc310-mnc260-ur/strings.xml
deleted file mode 100644
index 5e93fa7..0000000
--- a/core/res/res/values-mcc310-mnc260-ur/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi کالنگ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uz/strings.xml b/core/res/res/values-mcc310-mnc260-uz/strings.xml
deleted file mode 100644
index 19c8f2e..0000000
--- a/core/res/res/values-mcc310-mnc260-uz/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi qo‘ng‘iroqlar"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-vi/strings.xml b/core/res/res/values-mcc310-mnc260-vi/strings.xml
deleted file mode 100644
index 7b249c8..0000000
--- a/core/res/res/values-mcc310-mnc260-vi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"Gọi điện qua Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
deleted file mode 100644
index 7624e91..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"向您的运营商注册"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WLAN 通话功能"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
deleted file mode 100644
index 1aea15a..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"向您的流動網絡供應商註冊"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
deleted file mode 100644
index b0c7834..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"向您的行動通訊業者註冊"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zu/strings.xml b/core/res/res/values-mcc310-mnc260-zu/strings.xml
deleted file mode 100644
index cc32b1e..0000000
--- a/core/res/res/values-mcc310-mnc260-zu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You my obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
- </string-array>
- <string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
- </string-array>
- <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ukushaya kwe-Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 920f960..cd92c46 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено не се нуди од мобилната мрежа на вашата локација"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се дојде до мрежата"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"За подобрување на приемот, обидете се да го промените избраниот тип во „Поставки > Мрежа и интернет > Мобилни мрежи > Претпочитан тип мрежа“."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Предупредувања"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Проследување повик"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим на итен повратен повик"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Предупредувања за мобилен интернет"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-пораки"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Пораки од говорна пошта"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Повикување преку Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Регистрирајте се со операторот"</item>
+ <item msgid="7472393097168811593">"Регистрирајте се кај операторот (Код на грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помош"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Заклучи сега"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известување"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуелна тастатура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физичка тастатура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Безбедност"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за МИДИ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со USB додаток"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Допрете за повеќе опции."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиододатокот не е поддржан"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Допрете за повеќе информации"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Откриен е аналоген аудиододаток"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Приложениот уред не е компатибилен со телефонов. Допрете за да дознаете повеќе."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Се споделува извештај за грешки…"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 843262d..1284e64 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"നിങ്ങളുടെ ലൊക്കേഷനിൽ മൊബൈൽ നെറ്റ്വര്ക്ക് താൽക്കാലികമായി ലഭ്യമല്ല"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്യാനാവുന്നില്ല"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"സ്വീകരണം മെച്ചപ്പെടുത്തുന്നതിന് സിസ്റ്റം > നെറ്റ്വർക്കും ഇന്റെർനെറ്റും > മൊബൈൽ നെറ്റ്വർക്കുകൾ > തിരഞ്ഞെടുത്ത നെറ്റ്വർക്ക് തരം എന്നതിൽ തിരഞ്ഞെടുത്തിരിക്കുന്ന തരം മാറ്റിക്കൊണ്ട് ശ്രമിച്ചുനോക്കുക."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"അലേർട്ടുകൾ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"കോൾ ഫോർവേഡിംഗ്"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"അടിയന്തര കോൾബാക്ക് മോഡ്"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"മൊബൈൽ ഡാറ്റ അലേർട്ടുകൾ"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS സന്ദേശങ്ങൾ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"വോയ്സ്മെയിൽ സന്ദേശങ്ങൾ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"വൈഫൈ കോളിംഗ്"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"വൈഫൈ വഴി കോളുകൾ ചെയ്യാനും സന്ദേശങ്ങൾ അയയ്ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക. (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+ <item msgid="7472393097168811593">"നിങ്ങളുടെ കാരിയറുമായി രജിസ്റ്റർ ചെയ്യുക (പിശക് കോഡ്: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്സ് സഹായം"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ഇപ്പോൾ ലോക്കുചെയ്യുക"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"പുതിയ അറിയിപ്പ്"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"വെർച്വൽ കീബോർഡ്"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"കീബോർഡ്"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"സുരക്ഷ"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-യ്ക്കായുള്ള USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ഒരു USB ആക്സസ്സറി കണക്റ്റുചെയ്തു"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ഓഡിയോ ആക്സസറി പ്രവർത്തിക്കുകയില്ല"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പുചെയ്യുക"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"അനലോഗ് ഓഡിയോ ആക്സസറി കണ്ടെത്തി"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"അറ്റാച്ചുചെയ്ത ഉപകരണം ഈ ഫോണിന് അനുയോജ്യമല്ല. കൂടുതലറിയാൻ ടാപ്പുചെയ്യുക."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റുചെയ്തു"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നു…"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index ed9863c..c00346c 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Таны байршилд таны мобайл сүлжээнээс түр хугацаанд блоклосон"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сүлжээнд холбогдох боломжгүй байна"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Хүлээн авалтыг сайжруулахын тулд Тохиргоо > Сүлжээ & Интернэт > Мобайл сүлжээ > Сонгосон сүлжээний төрөл хэсгийг сонгон төрлөө өөрчилнө үү."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Сануулга"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Дуудлага шилжүүлэх"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Яаралтай дуудлага хийх горим"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Мобайл дата сануулга"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS мессеж"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Дуут шуудангийн мессеж"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi дуудлага"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi-аар дуудлага хийх, мессеж илгээх бол эхлээд оператор компаниасаа энэ үйлчилгээг тохируулж өгөхийг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу. (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Операторт бүртгүүлэх"</item>
+ <item msgid="7472393097168811593">"Оператор компаниар бүртгүүлэх (Алдааны код: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Дуут туслах"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Одоо түгжих"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Шинэ мэдэгдэл"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуал гар"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Бодит гар"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Аюулгүй байдал"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ийн USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Бусад сонголтыг харахын тулд товшино уу."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио хэрэгслийг дэмжээгүй байна"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Дэлгэрэнгүйг үзэхийн тулд товшино уу"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналог аудионы дагалдах хэрэгсэл илэрсэн"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Холбосон төхөөрөмж энэ утастай тохирохгүй байна. Дэлгэрэнгүй үзэх бол товшино уу."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB-н алдаа засварлахыг идэвхгүй болгохын тулд товшино уу."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 8fd7fe4..e99cb67 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"तुम्ही असलेल्या स्थानी मोबाइल नेटवर्क तात्पुरते उपलब्ध नाही"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कवर पोहोचूू शकत नाही"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्शन सुधारण्यासाठी, सोटिंग्ज > नेटवर्क आणि इंटरनेट > मोबाइल नेटवर्क > प्राधान्य दिलेला नेटवर्क प्रकार बदलून पहा."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्ट"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल फॉरवर्डिंग"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"इमर्जन्सी कॉलबॅक मोड"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटा अलर्ट"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"व्हॉइसमेल संदेश"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi कॉलिंग"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"आपल्या वाहकासह नोंदणी करा"</item>
+ <item msgid="7472393097168811593">"तुमच्या वाहकासह नोंदणी करा (एरर कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"आता लॉक करा"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"नवीन सूचना"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"व्हर्च्युअल कीबोर्ड"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"वास्तविक कीबोर्ड"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षितता"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI साठी USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB उपसाधनावर कनेक्ट केले"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"अधिक पर्यायांसाठी टॅप करा."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ऑडिओ अॅक्सेसरी समर्थित नाही"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"आणखी माहितीसाठी येथे टॅप करा"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"अॅनालॉग ऑडिओ अॅक्सेसरी आढळली"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"या फोनसह संलग्न केलेले डीव्हाइस सुसंगत नाही. अधिक जाणून घेण्यासाठी टॅप करा."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्ट केले"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करणे अक्षम करण्यासाठी टॅप करा."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"दोष अहवाल घेत आहे..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल सामायिक करायचा?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"दोष अहवाल सामायिक करीत आहे..."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index e0c1147..fb1b63b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Tidak ditawarkan oleh rangkaian mudah alih di lokasi anda untuk sementara waktu"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat mencapai rangkaian"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Untuk memperbaik penerimaan, cuba tukar jenis rangkaian yang dipilih di Tetapan > Rangkaian & Internet > Rangkaian mudah alih > Jenis rangkaian pilihan."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Panggilan Wi-Fi aktif"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Rangkaian mudah alih diperlukan untuk membuat panggilan kecemasan."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Makluman"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Pemajuan panggilan"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mod paggil balik kecemasan"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Makluman data mudah alih"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status data mudah alih"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mesej SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mesej mel suara"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Panggilan Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, minta pembawa anda menyediakan perkhidmatan ini terlebih dahulu. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan. (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Daftar dengan pembawa anda"</item>
+ <item msgid="7472393097168811593">"Daftar dengan pembawa anda (Kod ralat: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Pemberitahuan baharu"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Papan kekunci maya"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Papan kekunci fizikal"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Keselamatan"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Ketik untuk mendapatkan lagi pilihan."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori audio tidak disokong"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ketik untuk mendapatkan maklumat lanjut"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aksesori audio analog dikesan"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Peranti yang disambungkan tidak serasi dengan telefon ini. Ketik untuk mengetahui lebih lanjut."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ketik untuk melumpuhkan penyahpepijatan USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e7eb060..22a3d4f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"သင်၏ ဒေသတွင် မိုဘိုင်းကွန်ရက် ယာယီမရရှိနိုင်ပါ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ကွန်ရက်ကို ချိတ်ဆက်၍မရပါ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"လိုင်းဖမ်းယူမှု ကောင်းမွန်စေရန် ဆက်တင်များ > ကွန်ရက်နှင့် အင်တာနက် > မိုဘိုင်းကွန်ရက်များ > အသုံးပြုလိုသည့် ကွန်ရက်အမျိုးအစားတွင် ရွေးချယ်ထားသည့် အမျိုးအစားကို ပြောင်းကြည့်ပါ။"</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi ခေါ်ဆိုမှုကို အသုံးပြုနေပါသည်"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"အရေးပေါ်ဖုန်းခေါ်ဆိုရန် မိုဘိုင်းကွန်ရက်ကို လိုအပ်သည်။"</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"သတိပေးချက်များ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"အရေးပေါ် ပြန်လည်ခေါ်ဆိုနိုင်သောမုဒ်"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"မိုဘိုင်းဒေတာ သတိပေးချက်များ"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"မိုဘိုင်းဒေတာ အခြေအနေ"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS မက်ဆေ့ဂျ်များ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"အသံမေးလ် မက်ဆေ့ဂျ်များ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi ခေါ်ဆိုမှု"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Wi-Fi အသုံးပြု၍ ဖုန်းခေါ်ရန်နှင့် မက်ဆေ့ဂျ်ပို့ရန်အတွက် သင့်ဝန်ဆောင်မှုပေးသူကို ဤဝန်ဆောင်မှုအား သတ်မှတ်ပေးရန် ဦးစွာတောင်းဆိုပါ။ ထို့နောက် ဆက်တင်ထဲသို့ သွား၍ Wi-Fi ဖြင့် ဖုန်းခေါ်ခြင်းကို ဖွင့်ရပါမည်။ (အမှားကုဒ်- <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+ <item msgid="7472393097168811593">"သင့်ဖုန်းကုမ္ပဏီနှင့် မှတ်ပုံတင်ပါ (အမှားကုဒ်− <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"အသံ အကူအညီ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"အကြောင်းကြားချက်အသစ်"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ပကတိအသွင်ကီးဘုတ်"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ကီးဘုတ် ခလုတ်ခုံ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"လုံခြုံရေး"</string>
@@ -1157,7 +1158,7 @@
<string name="sim_restart_button" msgid="4722407842815232347">"အစက ပြန်စရန်"</string>
<string name="carrier_app_dialog_message" msgid="7066156088266319533">"သင့် SIM အသစ်ပုံမှန် အလုပ်လုပ်ရန်၊ သင်အသုံးပြုသည့် မိုဘိုင်းဝန်ဆောင်မှုမှ အက်ပ်တစ်ခုထည့်သွင်း၍ ဖွင့်ရန်လိုအပ်ပါသည်။"</string>
<string name="carrier_app_dialog_button" msgid="7900235513678617329">"အက်ပ်ကို ရယူပါ"</string>
- <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ယခုမဟုတ်သေးပါ"</string>
+ <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ယခုမလုပ်ပါ"</string>
<string name="carrier_app_notification_title" msgid="8921767385872554621">"SIM အသစ်ထည့်သွင်းလိုက်ပါသည်"</string>
<string name="carrier_app_notification_text" msgid="1132487343346050225">"၎င်းကိုတပ်ဆင်ရန် တို့ပါ"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"အချိန်သတ်မှတ်ရန်"</string>
@@ -1176,12 +1177,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI အတွက် USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBတွဲဖက်ပစ္စည်းအား ချိတ်ဆက်ထားသည်"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"အသံ ဆက်စပ်ပစ္စည်းကို မပံ့ပိုးပါ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"နောက်ထပ် အချက်အလက်များအတွက် တို့ပါ"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"အန်နာလော့ အသံကိရိယာကို တွေ့ထားပါသည်"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"တပ်ဆင်ထားသော ကိရိယာကို ဤဖုန်းနှင့် တွဲသုံး၍မရပါ။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ဆက်သွယ်ရေးစနစ်ကို ပိတ်ရန် တို့ပါ။"</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ချွတ်ယွင်းချက် အစီရင်ခံစာပြုစုနေသည်..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို မျှဝေမလား။"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ချွတ်ယွင်းမှုအစီရင်ခံစာ မျှဝေနေသည်…"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 4548b0b..3910fae 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbys midlertidig ikke gjennom mobilnettverket der du er"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Får ikke kontakt med nettverket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"For å forbedre signalet, prøv å endre valgt nettverkstype i Innstillinger > Nettverk og Internett > Mobilnettverk > Foretrukket nettverkstype."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Varsler"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Viderekobling"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modusen nødsamtale-tilbakeringing"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Varsler for mobildata"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-meldinger"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Talepostmeldinger"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-anrop"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrer deg hos operatøren din"</item>
+ <item msgid="7472393097168811593">"Registrer deg hos operatøren din (feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lås nå"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nytt varsel"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysisk tastatur"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Sikkerhet"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Trykk for å få flere alternativ."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret støttes ikke"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trykk for mer informasjon"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogt lydtilbehør ble oppdaget"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den tilkoblede enheten er ikke kompatibel med denne telefonen. Trykk for å finne ut mer."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Trykk for å slå av feilsøking via USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 3ac8c37..5ff2ad0 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"तपाईंको स्थानमा सञ्चालन भइरहेको मोबाइल नेटवर्कले अस्थायी रूपमा यो सुविधा प्रदान गर्दैन"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कमाथि पहुँच राख्न सकिँदैन"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"रिसेप्सनमा सुधार गर्न प्रणालीहरू > नेटवर्क तथा इन्टरनेट > मोबाइल नेटवर्कहरू > रुचाइएको नेटवर्कको प्रकारमा गई चयन गरिएको प्रकार परिवर्तन गरी हेर्नुहोस्।"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्टहरू"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"कल फर्वार्ड गर्ने सेवा"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपतकालीन कलब्याक मोड"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटाका अलर्टहरू"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS सन्देशहरू"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"भ्वाइस मेल सन्देशहरू"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi कल"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi मार्फत कलहरू गर्न र सन्देशहरू पठाउन सबभन्दा पहिला आफ्नो सेवा प्रदायकलाई यो सेवा सेट गर्न भन्नुहोस्। त्यसपछि सेटिङहरूबाट Wi-Fi कलिङलाई सक्रिय पार्नुहोस्। (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
+ <item msgid="7472393097168811593">"आफ्नो सेवा प्रदायकमा दर्ता गर्नुहोस् (त्रुटिसम्बन्धी कोड: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"अब बन्द गर्नुहोस्"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"नयाँ सूचना"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"भर्चुअल किबोर्ड"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"वास्तविक किबोर्ड"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षा"</string>
@@ -1182,11 +1186,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI को लागि USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"अडियोको सहायक सामग्रीलाई समर्थन छैन"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"थप जानकारीका लागि ट्याप गर्नुहोस्"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"एनालग अडियोको सहायक उपकरण पत्ता लाग्यो"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"संलग्न गरिएको यन्त्र यो फोनसँग कम्प्याटिबल छैन। थप जान्न ट्याप गर्नुहोस्।"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डिबगिङलाई असक्षम गर्न ट्याप गर्नुहोस्।"</string>
- <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङ असक्षम पार्न चयन गर्नुहोस्।"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट लिँदै..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्टलाई साझेदारी गर्ने हो?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्टलाई साझेदारी गर्दै ..."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c4adc03b..515aad6 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Tijdelijk niet aangeboden door het mobiele netwerk op je locatie"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk niet bereiken"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Als je de ontvangst wilt verbeteren, kun je het netwerktype wijzigen dat is geselecteerd bij Instellingen > Netwerk en internet > Mobiele netwerken > Voorkeursnetwerktype."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Bellen via wifi is actief"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Voor noodoproepen is een mobiel netwerk vereist."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Meldingen"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Oproep doorschakelen"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modus voor noodoproepen"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Meldingen voor mobiele data"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status van mobiele data"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Sms\'jes"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemailberichten"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Bellen via wifi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen. (Foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registreren bij je provider"</item>
+ <item msgid="7472393097168811593">"Registreer bij je provider (foutcode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Spraakassistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Nu vergrendelen"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nieuwe melding"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtueel toetsenbord"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysiek toetsenbord"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Beveiliging"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB voor MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Aangesloten op een USB-accessoire"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tik voor meer opties."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audioaccessoire niet ondersteund"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tik voor meer informatie"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoog audioaccessoire gedetecteerd"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Het aangesloten apparaat werkt niet met deze telefoon. Tik voor meer informatie."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-foutopsporing uit te schakelen."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 3adba7b..553ef62 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"ਤੁਹਾਡੇ ਟਿਕਾਣੇ \'ਤੇ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਵੱਲੋਂ ਉਪਲਬਧ ਨਹੀਂ ਕਰਵਾਈ ਗਈ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ਸਿਗਨਲ ਪ੍ਰਾਪਤੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਸੈਟਿੰਗਾਂ > ਨੈੱਟਵਰਕ ਅਤੇ ਇੰਟਰਨੈੱਟ > ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ > ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ \'ਤੇ ਜਾਓ ਅਤੇ ਚੁਣੀ ਗਈ ਕਿਸਮ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ਸੁਚੇਤਨਾਵਾਂ"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ਕਾਲ ਫਾਰਵਾਰਡਿੰਗ"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ਮੋਬਾਈਲ ਡੈਟਾ ਸੁਚੇਤਨਾਵਾਂ"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS ਸੁਨੇਹੇ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ਵੌਇਸਮੇਲ ਸੁਨੇਹੇ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi‑Fi ਕਾਲਿੰਗ"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਦੇ ਲਈ, ਸਭ ਤੋਂ ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਸ ਸੇਵਾ ਦੀ ਸਥਾਪਨਾ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਨੂੰ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ। (ਗੜਬੜੀ ਕੋਡ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
+ <item msgid="7472393097168811593">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਪੰਜੀਕਰਨ ਕਰੋ (ਗੜਬੜ ਕੋਡ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ਵੌਇਸ ਅਸਿਸਟ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ ਲੌਕ ਕਰੋ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"ਨਵੀਂ ਸੂਚਨਾ"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ਸੁਰੱਖਿਆ"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ਲਈ USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ਇੱਕ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ਔਡੀਓ ਉਪਸਾਧਨ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ਐਨਾਲੌਗ ਔਡੀਓ ਉਪਸਾਧਨ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"ਨੱਥੀ ਕੀਤੀ ਡੀਵਾਈਸ ਇਸ ਫ਼ੋਨ ਦੇ ਅਨੁਰੂਪ ਨਹੀਂ ਹੈ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 92ffc65..0395dcb 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Usługa tymczasowo nieoferowana przez sieć komórkową w Twojej lokalizacji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Brak zasięgu sieci"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Aby poprawić odbiór, zmień typ sieci: wybierz Ustawienia > Sieć i internet > Sieci komórkowe > Preferowany typ sieci."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerty"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Przekierowanie połączeń"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Tryb alarmowego połączenia zwrotnego"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alerty o mobilnej transmisji danych"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-y"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Wiadomości poczty głosowej"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Połączenia przez Wi-Fi"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach. (Kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Zarejestruj u operatora"</item>
+ <item msgid="7472393097168811593">"Rejestracja u operatora (kod błędu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Asystent głosowy"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nowe powiadomienie"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Klawiatura wirtualna"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Klawiatura fizyczna"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Bezpieczeństwo"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB w trybie MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Kliknij, by wyświetlić więcej opcji."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Nieobsługiwane akcesorium audio"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Kliknij, aby uzyskać więcej informacji"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Wykryto analogowe urządzenie audio"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Podłączone urządzenie nie jest zgodne z tym telefonem. Kliknij, by dowiedzieć się więcej."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Kliknij, by wyłączyć debugowanie USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 0d9e310..d25fa52 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a recepção, tente alterar o tipo selecionado em Configurações > Rede & Internet > Redes móveis > Tipo de rede preferencial."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"A chamada no Wi‑Fi está ativa"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"As chamadas de emergência exigem uma rede móvel."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Encaminhamento de chamada"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de retorno de chamada de emergência"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de dados móveis"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status dos dados móveis"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensagens SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensagens do correio de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Chamadas por Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
+ <item msgid="7472393097168811593">"Registre-se junto à sua operadora (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não compatível"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para mais informações"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detectado"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 91da103..3a4ae28 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente não disponibilizado pela rede móvel na sua localização"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não é possível ligar à rede"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a receção, experimente alterar o tipo selecionado em Definições > Rede e Internet > Redes móveis > Tipo de rede preferido."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Reencaminhamento de chamadas"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de chamada de retorno de emergência"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de dados móveis"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensagens SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensagens de correio de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Chamadas Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. De seguida, nas Definições, ative novamente as Chamadas Wi-Fi. (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registar-se junto do seu operador"</item>
+ <item msgid="7472393097168811593">"Registar-se junto do seu operador (código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. de voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ligado a um acessório USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para obter mais opções."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não suportado"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para obter mais informações"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detetado"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo ligado não é compatível com este telemóvel. Toque para saber mais."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 0d9e310..d25fa52 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Para melhorar a recepção, tente alterar o tipo selecionado em Configurações > Rede & Internet > Redes móveis > Tipo de rede preferencial."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"A chamada no Wi‑Fi está ativa"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"As chamadas de emergência exigem uma rede móvel."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Encaminhamento de chamada"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modo de retorno de chamada de emergência"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alertas de dados móveis"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status dos dados móveis"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mensagens SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensagens do correio de voz"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Chamadas por Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente a chamada no Wi-Fi nas configurações. Código de erro: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Faça registro na sua operadora"</item>
+ <item msgid="7472393097168811593">"Registre-se junto à sua operadora (Código de erro: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nova notificação"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teclado físico"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Segurança"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não compatível"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para mais informações"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detectado"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 73d1bc2..fef67cc 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -81,10 +81,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Momentan nu este oferit de rețeaua mobilă în locația dvs."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nu se poate stabili conexiunea la rețea"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Pentru o recepție mai bună, încercați să schimbați tipul selectat în Setări > Rețea și internet > Rețele mobile > Tip preferat de rețea."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Apelarea prin Wi-Fi este activă"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Apelurile de urgență necesită o rețea mobilă."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerte"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Redirecționarea apelurilor"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mod de apelare inversă de urgență"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Alerte de date mobile"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Starea datelor mobile"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Mesaje SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mesaje din mesageria vocală"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Apelare prin Wi-Fi"</string>
@@ -119,7 +121,7 @@
<item msgid="3910386316304772394">"Pentru a efectua apeluri și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări. (Cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Înregistrați-vă la operatorul dvs."</item>
+ <item msgid="7472393097168811593">"Înregistrați-vă la operator (cod de eroare: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Asistent vocal"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Blocați acum"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Notificare nouă"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastatură virtuală"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastatură fizică"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Securitate"</string>
@@ -1198,8 +1199,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"Conexiune USB pentru MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectat la un accesoriu USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Atingeți pentru mai multe opțiuni."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accesoriul audio nu este acceptat"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Atingeți pentru mai multe informații"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"S-a detectat un accesoriu audio analogic"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Dispozitivul atașat nu este compatibil cu acest telefon. Atingeți pentru a afla mai multe."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Atingeți ca să dezactivați remedierea erorilor prin USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva depanarea USB."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 58c981d..c79127a 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Местная мобильная сеть временно не поддерживает эту функцию."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сеть недоступна"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Чтобы улучшить сигнал, попробуйте выбрать другой тип сети в настройках (раздел \"Мобильные сети\")."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Оповещения"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Переадресация вызовов"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим экстренных обратных вызовов"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Оповещения, связанные с мобильным Интернетом"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Голосовые сообщения"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Звонки по Wi-Fi"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо подключить эту услугу через оператора связи. После этого вы сможете выбрать этот параметр в настройках. Код ошибки: <xliff:g id="CODE">%1$s</xliff:g>."</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Укажите оператора и зарегистрируйтесь"</item>
+ <item msgid="7472393097168811593">"Укажите оператора и зарегистрируйтесь (код ошибки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Аудиоподсказки"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Заблокировать"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Новое уведомление"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуальная клавиатура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физическая клавиатура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Безопасность"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI через USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Нажмите, чтобы показать дополнительные параметры."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоустройство не поддерживается"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Нажмите, чтобы получить дополнительную информацию"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Обнаружено аналоговое аудиоустройство"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Подсоединенное устройство несовместимо с этим телефоном. Нажмите, чтобы узнать подробности."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Нажмите, чтобы отключить отладку по USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 63d2d45..c8efd00 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"ඔබේ ස්ථානයේ ජංගම ජාලය මගින් තාවකාලිකව පිරිනොනමයි"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ජාලය වෙත ළඟා විය නොහැකිය"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ප්රතිග්රහණය වැඩි දියුණු කිරීමට, සැකසීම් > ජාලය සහ අන්තර්ජාලය > ජංගම ජාල > වඩා කැමති ජාල වර්ගය තුළ තෝරන ලද වර්ගය වෙනස් කිරීම උත්සාහ කරන්න."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"ඇඟවීම්"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"ඇමතුම ප්රතියොමු කිරීම"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"හදිසි අවස්ථා පසු ඇමතුම් ප්රකාරය"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ජංගම දත්ත ඇඟවීම්"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS පණිවිඩ"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"හඬ තැපැල් පණිවිඩ"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi ඇමතීම"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්රියාත්මක කරන්න. (දෝෂ කේතය <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
+ <item msgid="7472393097168811593">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න (දෝෂ කේතය: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"හඬ සහායක"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"දැන් අගුළු දමන්න"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"නව දැනුම්දීම"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"අතථ්ය යතුරු පුවරුව"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"භෞතික යතුරු පුවරුව"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ආරක්ෂාව"</string>
@@ -1178,8 +1182,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI සඳහා USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ශ්රව්ය ආයිත්තම සහාය නොදක්වයි"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ප්රතිසම ශ්රව්ය උපාංගය අනාවරණය කර ගන්නා ලදී"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"මෙම දුරකථනය සමඟ සම්බන්ධිත උපාංගය නොගැළපෙයි. තව දැන ගැනීමට තට්ටු කරන්න."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB නිදොස්කරණය අබල කිරීමට තට්ටු කරන්න."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 7be4b20..d4632e9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Momentálne nie sú v ponuke mobilnej siete na vašom mieste"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepodarilo sa pripojiť k sieti"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ak chcete vylepšiť príjem, skúste zmeniť vybraný typ v časti Nastavenia > Sieť a internet > Mobilné siete > Preferovaný typ siete."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornenia"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Presmerovanie hovorov"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim tiesňového spätného volania"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozornenia na mobilné dáta"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Správy SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Správy hlasovej schránky"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Volanie cez Wi-Fi"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi. (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrujte sa so svojím operátorom"</item>
+ <item msgid="7472393097168811593">"Zaregistrujte sa u operátora (Kód chyby: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Hlasový asistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Uzamknúť"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Nové upozornenie"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuálna klávesnica"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fyzická klávesnica"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Zabezpečenie"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB na pripojenie zariadenia MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Pripojené k periférnemu zariadeniu USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte ďalšie možnosti."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvukové príslušenstvo nie je podporované"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ďalšie informácie zobrazíte klepnutím"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Bolo zistené analógové zvukové príslušenstvo"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pripojené zariadenie nie je kompatibilné s týmto telefónom. Ďalšie informácie zobrazíte klepnutím."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladenie cez USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e0d05a7..6ba8721 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -82,10 +82,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Ta storitev trenutno ni na voljo v mobilnem omrežju na vaši lokaciji"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezave z omrežjem ni mogoče vzpostaviti"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Če želite izboljšati sprejem, poskusite zamenjati vrsto omrežja v »Nastavitve« > »Omrežje in internet« > »Mobilna omrežja« > »Prednostna vrsta omrežja«."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Opozorila"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmerjanje klicev"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Način za povratni klic v sili"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Opozorila o prenosu podatkov v mobilnem omrežju"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Sporočila SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Sporočila v odzivniku"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Klicanje prek Wi-Fi-ja"</string>
@@ -120,7 +125,7 @@
<item msgid="3910386316304772394">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi. (Koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registracija pri operaterju"</item>
+ <item msgid="7472393097168811593">"Registracija pri operaterju (koda napake: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +241,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zakleni zdaj"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Novo obvestilo"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Navidezna tipkovnica"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fizična tipkovnica"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Varnost"</string>
@@ -1220,8 +1224,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Dotaknite se za več možnosti."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvočna oprema ni podprta"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dotaknite se za več informacij"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Zaznana je analogna dodatna zvočna oprema"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključena naprava ni združljiva s tem telefonom. Dotaknite se za več informacij."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dotaknite se za izklop odpravljanja napak prek USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 793bad9..ca27780 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Përkohësisht nuk ofrohet nga rrjeti celular në vendndodhjen tënde"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Rrjeti i paarritshëm"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Për të përmirësuar marrjen e sinjalit, provo të ndryshosh llojin e zgjedhur te Cilësimet > Rrjeti dhe interneti > Lloji i preferuar i rrjetit."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Sinjalizimet"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Transferimi i telefonatave"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Modaliteti i \"Kthimit të telefonatës së urgjencës\""</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Sinjalizimet për të dhënat celulare"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Mesazhet SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mesazhet e postës zanore"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Telefonata me Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Për të bërë telefonata dhe për të dërguar mesazhe nëpërmjet Wi-Fi, në fillim kërkoji operatorit celular të konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi nga \"Cilësimet\". (Kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Regjistrohu me operatorin tënd celular"</item>
+ <item msgid="7472393097168811593">"Regjistrohu me operatorin tënd celular (kodi i gabimit: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ndihma zanore"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Kyç tani"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Njoftim i ri"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastiera virtuale"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tastiera fizike"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Siguria"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB për MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"U lidh me një ndihmës USB-je"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Trokit për më shumë opsione."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori i audios nuk mbështetet"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trokit për më shumë informacion"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"U zbulua aksesor i audios analoge"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pajisja e bashkuar nuk është e pajtueshme me këtë telefon. Trokit për të mësuar më shumë."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Trokit për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Po ndan raportin e defekteve në kod..."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a9e3af9..bbd9dba 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -81,10 +81,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено је онемогућено на мобилној мрежи на вашој локацији"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Повезивање са мрежом није успело"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Да бисте побољшали пријем, пробајте да промените изабрани тип у одељку Подешавања > Мрежа и интернет > Мобилне мреже > Жељени тип мреже."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Обавештења"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Преусмеравање позива"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим за хитан повратни позив"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Обавештења за мобилне податке"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-ови"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Поруке говорне поште"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Позивање преко Wi-Fi мреже"</string>
@@ -119,7 +124,7 @@
<item msgid="3910386316304772394">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја. (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Региструјте се код мобилног оператера"</item>
+ <item msgid="7472393097168811593">"Региструјте се код мобилног оператера (кôд грешке: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -233,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помоћ"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Закључај одмах"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ново обавештење"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуелна тастатура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Физичка тастатура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Безбедност"</string>
@@ -1198,8 +1202,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Повезано са USB додатком"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Додирните за још опција."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Додатна опрема за аудио садржај није подржана"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Додирните за више информација"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Откривена је аналогна додатна опрема за аудио садржај"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Прикључени уређај није компатибилан са овим телефоном. Додирните да бисте сазнали више."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је омогућено"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 72f9d6f..5880152 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Detta erbjuds för tillfället inte på mobilnätverket där du befinner dig"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Det går inte att nå nätverket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Testa om du får bättre mottagning genom att ändra till en annan typ under Inställningar > Nätverk och internet > Mobila nätverk > Önskad nätverkstyp."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi-Fi-samtal är aktiverat"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Mobilnätverk krävs för att ringa nödsamtal."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Aviseringar"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Vidarekoppla samtal"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Läget Återuppringning vid nödsamtal"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Aviseringar för mobildata"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status för mobildata"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Sms"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Röstmeddelanden"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-samtal"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar. (Felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Registrera dig hos operatören"</item>
+ <item msgid="7472393097168811593">"Registrera dig hos operatören (felkod: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Ny avisering"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuellt tangentbord"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysiskt tangentbord"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Säkerhet"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB för MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ansluten till ett USB-tillbehör"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Tryck för fler alternativ."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ljudtillbehöret stöds inte"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryck för mer information"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Ett tillbehör med analog ljudutgång hittades"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Den anslutna enheten är inte kompatibel med mobilen. Tryck här om du vill veta mer."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tryck om du vill inaktivera USB-felsökning."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1532b5b5..b71c794 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Kwa sasa, huduma hii haipatikani katika mtandao wa simu mahali ulipo"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Haiwezi kufikia mtandao"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ili kupata mtandao thabiti, jaribu kubadilisha aina uliyochagua katika Mipangilio > Mtandao na Intaneti > Mitandao ya simu > Aina ya mtandao unaopendelea."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Umewasha kipengele cha kupiga simu kupitia Wi‑Fi"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Huduma ya kupiga simu za dharura inahitaji mtandao wa simu."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Arifa"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Kupeleka simu kwenye nambari nyingine"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Hali ya kupiga simu za dharura"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Arifa za matumizi ya data ya simu"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Hali ya data ya mtandao wa simu"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Ujumbe wa SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Ujumbe wa sauti"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Kupiga simu kupitia Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako aweke mipangilio ya huduma hii kwanza. Kisha uwashe tena kipengele cha kupiga simu kupitia Wi-Fi kwenye Mipangilio. (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Jisajili na mtoa huduma wako"</item>
+ <item msgid="7472393097168811593">"Jisajili na mtoa huduma wako (Msimbo wa hitilafu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<!-- String.format failed for translation -->
<!-- no translation found for wfcSpnFormats:0 (6830082633573257149) -->
@@ -228,8 +230,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Usaidizi wa Sauti"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Arifa mpya"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Kibodi pepe"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Kibodi halisi"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Usalama"</string>
@@ -351,9 +352,9 @@
<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Huruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye runinga yako, pamoja na marudio ya upigaji wako wa simu, utumaji wa barua pepe, au mawasiliano kwa njia nyingine na watu maalum unaowasiliana nao. Idhini hii huruhusu programu kuhifadhi data yako ya mawasiliano, na programu hasidi zinaweza kushiriki data ya mawasiliano bila wewe kujua."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"kurekebisha anwani zako"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
<string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Huruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye runinga yako, pamoja na marudio ya upigaji wako wa simu, utumaji wa barua pepe, au mawasiliano kwa njia nyingine na watu maalum unaowasiliana nao. Ruhusa hii huruhusu programu kufuta data ya anwani."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye simu yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"kusoma rekodi ya simu"</string>
<string name="permdesc_readCallLog" msgid="3204122446463552146">"Programu hii inaweza kusoma rekodi yako ya simu zilizopigwa."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"kuandika rekodi ya simu"</string>
@@ -1174,8 +1175,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB kwa ajili ya MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Imeunganishwa kwa kifuasi cha USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Gonga ili upate chaguo zaidi."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Kifuasi cha sauti hakiwezi kutumika"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Gonga ili upate maelezo zaidi"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Imetambua kifaa cha sauti ya analogi"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Kifaa ulichoambatisha hakitumiki kwenye simu hii. Gonga ili upate maelezo zaidi."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Gonga ili uzime utatuaji wa USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index d348ba5..a33ffb5 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"தற்காலிகமாக உங்கள் இருப்பிடத்தில் மொபைல் நெட்வொர்க் வழங்கவில்லை"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"பெறுதலை மேம்படுத்த, அமைப்புகள் > நெட்வொர்க் & இணையம் > மொபைல் நெட்வொர்க்குகள் > விரும்பும் நெட்வொர்க் வகை என்பதற்குச் சென்று, தேர்ந்தெடுத்த வகையை மாற்றவும்."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"விழிப்பூட்டல்கள்"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"அழைப்புப் பகிர்வு"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"அவசரகாலத் திரும்ப அழைக்கும் பயன்முறை"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"மொபைல் தரவு விழிப்பூட்டல்கள்"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS செய்திகள்"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"குரலஞ்சல் செய்திகள்"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"வைஃபை அழைப்பு"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"வைஃபை மூலம் அழைக்கவும் செய்திகளை அனுப்பவும், முதலில் தொலைத்தொடர்பு நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும். (பிழைக் குறியீடு <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+ <item msgid="7472393097168811593">"உங்கள் தொலைத்தொடர்பு நிறுவனத்தில் பதிவுசெய்யவும் (பிழைக் குறியீடு: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"இப்போது பூட்டு"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"புதிய அறிவிப்பு"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"விர்ச்சுவல் விசைப்பலகை"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"கைமுறை விசைப்பலகை"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"பாதுகாப்பு"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB, MIDIக்கு மட்டும்"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB துணைக்கருவியுடன் இணைக்கப்பட்டுள்ளது"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"மேலும் விருப்பங்களுக்கு, தட்டவும்."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ஆடியோ துணைக்கருவி ஆதரிக்கப்படவில்லை"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"மேலும் தகவலுக்கு, தட்டவும்"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"அனலாக் ஆடியோ துணைக்கருவி கண்டறியப்பட்டது"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"இணைத்துள்ள சாதனமானது இந்த மொபைலுடன் இணங்கவில்லை. மேலும் அறிய, தட்டவும்."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB பிழை திருத்தத்தை முடக்க, தட்டவும்."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைத்திருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"பிழை அறிக்கையைப் பகிர்கிறது…"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 0e38833..e930079 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"మీ స్థానంలో మొబైల్ నెట్వర్క్ ద్వారా తాత్కాలికంగా అందించబడదు"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"నెట్వర్క్ను చేరుకోలేరు"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"స్వీకరణను మెరుగుపరచాలంటే, సెట్టింగ్లు > నెట్వర్క్ & ఇంటర్నెట్ > మొబైల్ నెట్వర్క్లు > ప్రాధాన్య నెట్వర్క్ రకంలో మీరు ఎంచుకున్న రకాన్ని మార్చి ప్రయత్నించండి."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"హెచ్చరికలు"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"కాల్ ఫార్వార్డింగ్"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"అత్యవసర కాల్బ్యాక్ మోడ్"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"మొబైల్ డేటా హెచ్చరికలు"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS సందేశాలు"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"వాయిస్ మెయిల్ సందేశాలు"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi కాలింగ్"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fiతో కాల్లను చేయడానికి మరియు సందేశాలను పంపించడానికి, మొదట ఈ సేవను సెటప్ చేయాల్సిందిగా మీ క్యారియర్కి చెప్పండి. ఆ తర్వాత సెట్టింగ్ల నుండి Wi-Fi కాలింగ్ని మళ్లీ ఆన్ చేయండి. (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"మీ క్యారియర్తో నమోదు చేయండి"</item>
+ <item msgid="7472393097168811593">"మీ క్యారియర్తో నమోదు చేయండి (లోపం కోడ్: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ సహాయకం"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"కొత్త నోటిఫికేషన్"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"వర్చువల్ కీబోర్డ్"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"భౌతిక కీబోర్డ్"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"భద్రత"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI కోసం USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ఉపకరణానికి కనెక్ట్ చేయబడింది"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ఆడియో ఉపకరణానికి మద్దతు లేదు"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"మరింత సమాచారం కోసం నొక్కండి"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"అనలాగ్ ఆడియో ఉపకరణం కనుగొనబడింది"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"జోడించిన పరికరం ఈ ఫోన్కు అనుకూలంగా లేదు. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB డీబగ్గింగ్ను నిలిపివేయడానికి నొక్కండి."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్ని నిలిపివేయడానికి ఎంచుకోండి."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"బగ్ నివేదికను భాగస్వామ్యం చేస్తోంది..."</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index d62b93e..cf67abf 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -39,4 +39,7 @@
<!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
<bool name="config_useDefaultFocusHighlight">false</bool>
+
+ <!-- Allow SystemUI to show the shutdown dialog -->
+ <bool name="config_showSysuiShutdown">false</bool>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 69f57bb..377ddb0 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"งดให้บริการชั่วคราวโดยเครือข่ายมือถือในตำแหน่งของคุณ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"เข้าถึงเครือข่ายไม่ได้"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ลองเปลี่ยนประเภทที่เลือกใน \"การตั้งค่า\" > \"เครือข่ายและอินเทอร์เน็ต\" > \"เครือข่ายมือถือ\" > \"ประเภทเครือข่ายที่ต้องการ\" เพื่อให้การรับสัญญาณดีขึ้น"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"การแจ้งเตือน"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"การโอนสาย"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"โหมดติดต่อกลับฉุกเฉิน"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"การแจ้งเตือนอินเทอร์เน็ตมือถือ"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"ข้อความ SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"ข้อความเสียง"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"การโทรผ่าน Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"ลงทะเบียนกับผู้ให้บริการ"</item>
+ <item msgid="7472393097168811593">"ลงทะเบียนกับผู้ให้บริการของคุณ (รหัสข้อผิดพลาด: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"ตัวช่วยเสียง"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ล็อกเลย"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"การแจ้งเตือนใหม่"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"แป้นพิมพ์เสมือน"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"แป้นพิมพ์บนเครื่อง"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"ความปลอดภัย"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB สำหรับ MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ไม่รองรับอุปกรณ์เสริมสำหรับเสียง"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"ตรวจพบอุปกรณ์เสริมสำหรับเสียงแบบแอนะล็อก"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"อุปกรณ์ที่พ่วงไม่สามารถใช้งานร่วมกับโทรศัพท์นี้ แตะเพื่อเรียนรู้เพิ่มเติม"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน USB แล้ว"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"แตะเพื่อปิดใช้การแก้ไขข้อบกพร่องของ USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index afb3cbd..977b855 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Pansamantalang hindi inaalok ng mobile network sa iyong lokasyon"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Hindi maabot ang network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Upang mapahusay ang reception, subukang baguhin ang uring napili sa Mga Setting > Network at Internet > Mga mobile network > Gustong uri ng network."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Mga Alerto"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Pagpasa ng tawag"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Emergency callback mode"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mga alerto ng mobile data"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Mga mensaheng SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mga mensahe sa voicemail"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Pagtawag gamit ang Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Upang makatawag at makapagpadala ng mga mensahe sa Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay i-on muli ang pagtawag gamit ang Wi-Fi mula sa Mga Setting. (Error code: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Magparehistro sa iyong carrier"</item>
+ <item msgid="7472393097168811593">"Iparehistro sa iyong carrier (Code ng error: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"I-lock ngayon"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Bagong notification"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual na keyboard"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Pisikal na keyboard"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Seguridad"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para sa MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang accessory ng USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"I-tap para sa higit pang mga opsyon."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Hindi sinusuportahan ang audio accessory"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"I-tap para sa higit pang impormasyon"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"May na-detect na analog na audio accessory"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Hindi tugma sa teleponong ito ang naka-attach na device. I-tap upang matuto pa."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"I-tap upang i-disable ang pag-debug ng USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8d14b24..f7a11eb5 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Bulunduğunuz yerdeki mobil ağ tarafından geçici olarak sunulmuyor"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ağa erişilemiyor"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Sinyal gücünü iyileştirmek için Ayarlar > Ağ ve İnternet > Mobil ağlar > Tercih edilen ağ türü bölümünde seçili türü değiştirmeyi deneyin."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Kablosuz çağrı etkin"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Acil durum çağrıları için mobil ağ gereklidir."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Uyarılar"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Çağrı yönlendirme"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Acil geri arama modu"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobil veri uyarıları"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Mobil veri durumu"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS mesajları"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Sesli mesajlar"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Kablosuz çağrı"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Kablosuz ağ üzerinden telefon etmek ve mesaj göndermek için öncelikle operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın. (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Operatörünüze kaydolun"</item>
+ <item msgid="7472393097168811593">"Operatörünüze kaydettirin (Hata kodu: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Şimdi kilitle"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Yeni bildirim"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Sanal klavye"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fiziksel klavye"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Güvenlik"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI için USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Diğer seçenekler için dokunun."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ses aksesuarı desteklenmiyor"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Daha fazla bilgi için dokunun"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analog ses aksesuarı algılandı"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Takılan cihaz bu telefonla uyumlu değil. Daha fazla bilgi edinmek için dokunun."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 5f25051..6481948 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -82,10 +82,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Тимчасово не пропонується мобільною мережею у вашому місцезнаходженні"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не вдається під’єднатися до мережі"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Щоб покращити прийняття сигналу, змініть тип у меню \"Налаштування\" > \"Мережа й Інтернет\" > \"Мобільні мережі\" > \"Тип мережі\"."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Виклики через Wi-Fi активовано"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Щоб здійснювати екстрені виклики, потрібне з’єднання з мобільною мережею."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Сповіщення"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Переадресація виклику"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Режим екстреного зворотного виклику"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Сповіщення про мобільне передавання даних"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Статус мобільного передавання даних"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS-повідомлення"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Повідомлення голосової пошти"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Дзвінки через Wi-Fi"</string>
@@ -120,7 +122,7 @@
<item msgid="3910386316304772394">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього знову ввімкніть дзвінки через Wi-Fi у налаштуваннях. (Код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Зареєструйтеся в оператора"</item>
+ <item msgid="7472393097168811593">"Зареєструйтеся в оператора (код помилки: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -236,8 +238,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Голос. підказки"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Блокувати зараз"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Нове сповіщення"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Віртуальна клавіатура"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Фізична клавіатура"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Безпека"</string>
@@ -1220,8 +1221,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для режиму MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Під’єднано до аксесуара USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Торкніться, щоб переглянути більше опцій."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аксесуар для аудіо не підтримується"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Торкніться, щоб дізнатися більше"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Виявлено аналоговий аксесуар для аудіо"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Під’єднаний пристрій несумісний із цим телефоном. Торкніться, щоб дізнатися більше."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Торкніться, щоб вимкнути налагодження USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index dc0fbb7..3247478 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"عارضی طور پر آپ کے مقام پر موبائل نیٹ ورک کی طرف سے پیش نہیں ہے"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"نیٹ ورک تک نہیں پہنچا جا سکتا"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"ریسپشن کو بہتر بنانے کیلئے، ترتیبات > نیٹ ورک اور انٹرنیٹ > موبائل نیٹ ورکس > ترجیحی نیٹ ورک کی قسم تبدیل کرنے کی کوشش کریں۔"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"الرٹس"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"کال آگے منتقل کرنا"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ہنگامی کال بیک وضع"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"موبائل ڈیٹا الرٹس"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS پیغامات"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"صوتی میل پیغامات"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi کالنگ"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کے لیے، پہلے اپنے کیریئر سے اس سروس کو سیٹ اپ کرنے کے لیے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔ (خراب کوڈ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
+ <item msgid="7472393097168811593">"اپنے کیریئر (خرابی کا کوڈ: <xliff:g id="CODE">%1$s</xliff:g>) کے ساتھ رجسٹر کریں"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"ابھی مقفل کریں"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"نئی اطلاع"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ورچوئل کی بورڈ"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"فزیکل کی بورڈ"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"سیکیورٹی"</string>
@@ -1176,12 +1180,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI کیلئے USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ایک USB لوازم سے مربوط ہے"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"آڈیو لوازم تعاون یافتہ نہیں ہے"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"مزید معلومات کے لیے تھپتھپائيں"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"اینالاگ آڈیو کے لوازم کا پتہ چلا"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"منسلک آلہ اس فون کے موافق نہیں ہے۔ مزید جاننے کے لیے تھپتھپائیں۔"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ڈیبگ کرنا مربوط ہو گیا"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ڈیبگنگ کو غیر فعال کرنے کیلئے تھپتھپائیں۔"</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"بگ رپورٹ کا اشتراک ہو رہا ہے…"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 9fe7274..70b2e16 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Hududingizda mobil tarmoq tomonidan vaqtinchalik taklif etilmayapti"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tarmoq bilan bog‘lanib bo‘lmadi"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Qabul qilish sifatini yaxshilash uchun Sozlamalar > Tarmoq va Internet > Mobil tarmoqlar > Asosiy tarmoq turi orqali o‘zgartirib ko‘ring."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Wi‑Fi chaqiruv faol"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Favqulodda chaqiruvlar uchun mobil internet zarur."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Ogohlantirishlar"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Chaqiruvlarni uzatish"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Favqulodda qaytarib chaqirish rejimi"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Mobil internetga oid ogohlantirishlar"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Mobil internet holati"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"SMS xabarlar"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Ovozli xabarlar"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi chaqiruv"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin. (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+ <item msgid="7472393097168811593">"Aloqa operatoringiz bilan ro‘yxatdan o‘ting (Xato kodi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Ovozli yordam"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Qulflash"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Yangi bildirishnoma"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtual klaviatura"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Tashqi klaviatura"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Xavfsizlik"</string>
@@ -1176,12 +1177,11 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB orqali MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB jihozga ulangan"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Boshqa parametrlarini ko‘rish uchun bosing."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio aksessuar ishlamaydi"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tafsilotlar uchun bosing"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analogli audio uskuna aniqlandi"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Biriktirilgan qurilma mazkur telefon bilan mos emas. Batafsil axborot olish uchun bu yerga bosing."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Faolsizlantirish uchun bu yerga bosing."</string>
- <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
- <skip />
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Xatoliklar hisoboti yuborilmoqda…"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d44924e..2a92793 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Tạm thời không được cung cấp bởi mạng di động tại vị trí của bạn"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Không thể kết nối mạng"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Cài đặt > Mạng và Internet > Mạng di động > Loại mạng ưa thích."</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Thông báo"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Chuyển tiếp cuộc gọi"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Chế độ gọi lại khẩn cấp"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Thông báo dữ liệu di động"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"Tin nhắn SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Thư thoại"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Gọi qua Wi-Fi"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt. (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
+ <item msgid="7472393097168811593">"Đăng ký với nhà cung cấp dịch vụ của bạn (Mã lỗi: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Khóa ngay"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Thông báo mới"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Bàn phím ảo"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Bàn phím thực"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Bảo mật"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB cho MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Nhấn để biết thêm tùy chọn."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Phụ kiện âm thanh không được hỗ trợ"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Nhấn để biết thêm thông tin"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Đã phát hiện phụ kiện âm thanh analog"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Thiết bị được kết nối không tương thích với điện thoại này. Nhấn để tìm hiểu thêm."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối gỡ lỗi USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Nhấn để vô hiệu hóa gỡ lỗi USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
diff --git a/core/res/res/values-watch/colors_device_defaults.xml b/core/res/res/values-watch/colors_device_defaults.xml
index 15786b4..654e92c 100644
--- a/core/res/res/values-watch/colors_device_defaults.xml
+++ b/core/res/res/values-watch/colors_device_defaults.xml
@@ -17,8 +17,87 @@
<!-- Colors specific to DeviceDefault themes. These are mostly pass-throughs to enable
overlaying new theme colors. -->
<resources>
+
+ <!--
+ primary_device_default_dark
+ > from values/colors_material/primary_material_dark
+ > from values/colors_material/material_grey_900
+ = #ff212121
+ ! replaced with custom color #33ffffff
+ -->
+ <color name="primary_device_default_dark">#33ffffff</color>
+ <!--
+ primary_dark_device_default_dark
+ > from values/colors_material/primary_dark_material_dark
+ = @color/black
+ -->
+ <color name="primary_dark_device_default_dark">@color/black</color>
+ <!--
+ accent_device_default_dark
+ > from values/colors_material/accent_material_dark
+ > from values/colors_material/material_deep_teal_200
+ = #ff80cbc4
+ ! replaced with custom color #5E97F6
+ -->
+ <color name="accent_device_default_dark">#5E97F6</color>
+ <!--
+ background_device_default_dark
+ > from values/colors_material/background_material_dark
+ > from values/colors_material/material_grey_850
+ = #ff303030
+ ! replaced with custom color #232E33
+ -->
+ <color name="background_device_default_dark">#232E33</color>
+ <!--
+ background_floating_device_default_dark
+ > from values/colors_material/background_floating_material_dark
+ > from values/colors_material/material_grey_800
+ = #ff424242
+ ! replaced with custom color #3E5059
+ -->
+ <color name="background_floating_device_default_dark">#3E5059</color>
+
+ <!--
+ background_cache_hint_selector_device_default
+ - note that this is based off of colors/background_cache_hint_selector_device_default
+ xml drawable
+ - uses ?attr/colorBackground and transparency to draw
+ - no color customization required here
+ -->
+
+ <!--
+ button_normal_device_default_dark
+ - uses ?attr/disabledAlpha and button_material_dark to draw
+ - cloned to watch_btn_default.xml drawable
+ (btn_default_material_dark & button_material_dark - see
+ values-watch/colors_material.xml)
+ -->
<color name="button_normal_device_default_dark">@color/btn_default_material_dark</color>
+
<!-- Use the same value as for accent_device_default_dark but start with #99,
i.e. 60% opacity -->
<color name="accent_device_default_dark_60_percent_opacity">#995E97f6</color>
+
+ <!--
+ foreground_device_default_dark
+ - introduced to avoid coupling to foreground_material_dark
+ - colorForeground typically falls through Theme.DeviceDefault to Theme.Material
+ -->
+ <color name="foreground_device_default_dark">@color/white</color>
+
+ <!--
+ error_color_device_default_dark
+ - introduced to avoid coupling to error_color_material (also #F4511E)
+ - colorError typically falls through Theme.DeviceDefault to Theme.Material
+ -->
+ <color name="error_color_device_default_dark">#F4511E</color>
+
+ <!-- deprecated for Wear
+ these overrides exist only for compatibility with existing
+ WTS theme test heuristics, based on the previous modifications
+ to the material theme, they should not be used for customization
+ as they are not exposed via publicly accessible attributes -->
+ <color name="accent_device_default_700">#5385DB</color>
+ <color name="accent_device_default_light">#75A4F5</color>
+ <color name="accent_device_default_50">#93B7F5</color>
</resources>
diff --git a/core/res/res/values-watch/colors_material.xml b/core/res/res/values-watch/colors_material.xml
index 72f589b..b19820c 100644
--- a/core/res/res/values-watch/colors_material.xml
+++ b/core/res/res/values-watch/colors_material.xml
@@ -14,15 +14,8 @@
limitations under the License.
-->
<resources>
- <color name="background_material_dark">#232E33</color>
- <color name="background_floating_material_dark">#3E5059</color>
- <color name="accent_material_700">#5385DB</color>
- <color name="accent_material_light">#75A4F5</color>
- <color name="accent_material_dark">#5E97F6</color>
- <color name="accent_material_50">#93B7F5</color>
+ <!-- referenced in colors/watch_btn_default.xml selector -->
+ <color name="button_material_dark">#ff919699</color>
- <color name="primary_material_dark">#33ffffff</color>
-
- <color name="button_material_dark">#ff919699</color>
</resources>
diff --git a/core/res/res/values-watch/dimens_device_defaults.xml b/core/res/res/values-watch/dimens_device_defaults.xml
new file mode 100644
index 0000000..ac0fcb8
--- /dev/null
+++ b/core/res/res/values-watch/dimens_device_defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <!-- Alpha transparency for wigets that set enablement/disablement programmatically
+ transparency is applied in the disabled state -->
+ <dimen name="disabled_alpha_device_default">0.5</dimen>
+ <!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) -->
+ <dimen name="primary_content_alpha_device_default">1.0</dimen>
+ <!-- Alpha transparency applied to elements which are considered secondary (e.g. secondary text) -->
+ <dimen name="secondary_content_alpha_device_default">0.8</dimen>
+</resources>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 4d210f6..f6752c2 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -37,11 +37,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar -->
@@ -49,11 +54,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar. This theme
@@ -62,11 +72,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -77,11 +92,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -91,11 +111,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Theme used for the intent picker activity. -->
@@ -134,11 +159,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for a window that should look like the Settings app. -->
@@ -156,11 +186,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<style name="Theme.DeviceDefault.Settings.CompactMenu" parent="Theme.Material.CompactMenu">
@@ -168,11 +203,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -182,11 +222,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -195,11 +240,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -209,11 +259,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
@@ -222,11 +277,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -236,11 +296,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -248,11 +313,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -262,11 +332,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -275,11 +350,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -288,11 +368,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<!-- DeviceDefault style for input methods, which is used by the
@@ -301,11 +386,16 @@
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -314,22 +404,32 @@
<!-- Color palette Dialog -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">@color/background_device_default_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
<style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -337,10 +437,15 @@
<!-- Color palette Dialog -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
<item name="colorBackground">?attr/colorBackgroundFloating</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
<item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
+ <item name="colorError">@color/error_color_device_default_dark</item>
+ <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
+ <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
+ <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9c11b40..6e951d3 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的移动网络暂时不提供这项服务"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"无法连接网络"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"要改善信号情况,请尝试更改在“设置”>“网络和互联网”>“移动网络”>“首选网络类型”中选择的类型。"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"提醒"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"来电转接"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"紧急回拨模式"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"移动数据提醒"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"短信"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"语音邮件"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"WLAN 通话"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)。"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"向您的运营商注册"</item>
+ <item msgid="7472393097168811593">"向您的运营商注册(错误代码:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虚拟键盘"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"实体键盘"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"正在通过 USB 连接到 MIDI 接口"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到USB配件"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"点按即可查看更多选项。"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"音频配件不受支持"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"点按即可了解详情"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"检测到模拟音频配件"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"连接的设备与此手机不兼容。点按即可了解详情。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到 USB 调试"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"点按即可停用 USB 调试功能。"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b361443..9e76764 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的流動網絡暫不提供這項服務"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連接網絡"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"如要接收更強訊號,請前往 [設定] > [網絡與互聯網] > [流動網絡] > [偏好的網絡類型] 更改網絡類型。"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"來電轉駁"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急回撥模式"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"流動數據通知"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"短訊"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"留言訊息"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"向您的流動網絡供應商註冊"</item>
+ <item msgid="7472393097168811593">"向您的流動網絡供應商註冊 (錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"語音助手"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"實體鍵盤"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"輕按即可查看更多選項。"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕按即可瞭解詳情"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"偵測到模擬音頻配件"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"連接的裝置與這部手機不兼容。輕按即可瞭解詳情。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"輕按即可停用 USB 偵錯功能。"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 25ecccc..2118e43 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -80,10 +80,15 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"你所在位置的行動網路暫時不提供這項服務"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連上網路"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"如要改善收訊狀況,請依序開啟 [設定] > [網路與網際網路] > [行動網路] > [偏好的網路類型],然後選取其他網路類型。"</string>
+ <!-- no translation found for EmergencyCallWarningTitle (4790413876281901612) -->
+ <skip />
+ <!-- no translation found for EmergencyCallWarningSummary (8973232888021643293) -->
+ <skip />
<string name="notification_channel_network_alert" msgid="4427736684338074967">"快訊"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"來電轉接"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"緊急回撥模式"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"行動數據快訊"</string>
+ <!-- no translation found for notification_channel_mobile_data_status (4575131690860945836) -->
+ <skip />
<string name="notification_channel_sms" msgid="3441746047346135073">"簡訊"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"語音留言"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
@@ -118,7 +123,7 @@
<item msgid="3910386316304772394">"如要透過 Wi-Fi 網路撥打電話及傳送訊息,請先要求電信業者為你設定這項服務,然後再次前往「設定」頁面啟用 Wi-Fi 通話功能。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"向你的電信業者註冊"</item>
+ <item msgid="7472393097168811593">"向你的電信業者註冊 (錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +235,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"實體鍵盤"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"安全性"</string>
@@ -1176,8 +1180,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接 USB 配件"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"輕觸即可查看更多選項。"</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"偵測到類比音訊配件"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"此外接裝置與這支手機不相容。輕觸即可瞭解詳情。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 2a17a96..ba8a53b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -80,10 +80,12 @@
<string name="RestrictedStateContent" msgid="4278821484643362350">"Okwesikhashana akunikezwa inethiwekhi yeselula endaweni yakho"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ayikwazi ukufinyelela inethiwekhi"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="1203771446683319957">"Ukuze uthuthukise ukwamukelwa, zama ukushintsha uhlobo olukhethiwe kuzilungiselelo > Inethiwekhi ne-inthanethi > amanethiwekhi eselula > Uhlobo oluncanyelwayo lwenethiwekhi."</string>
+ <string name="EmergencyCallWarningTitle" msgid="4790413876281901612">"Ukushaya kwe-Wi-Fi kuyasebenza"</string>
+ <string name="EmergencyCallWarningSummary" msgid="8973232888021643293">"Amakholi aphuthumayo adinga inethiwekhi yeselula."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"Izexwayiso"</string>
<string name="notification_channel_call_forward" msgid="2419697808481833249">"Ukudlulisa ikholi"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Imodi yokushayela yesimo esiphuthumayo"</string>
- <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Izexwayiso zedatha yeselula"</string>
+ <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Isimo sedatha yeselula"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"Imilayezo ye-SMS"</string>
<string name="notification_channel_voice_mail" msgid="3954099424160511919">"Imilayezo yevoyisimeyili"</string>
<string name="notification_channel_wfc" msgid="2130802501654254801">"Ukushaya kwe-Wi-Fi"</string>
@@ -118,7 +120,7 @@
<item msgid="3910386316304772394">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le sevisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="6177300162212449033">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+ <item msgid="7472393097168811593">"Bhalisa ngenkampani yakho yenethiwekhi (Ikhodi yephutha: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
@@ -230,8 +232,7 @@
<string name="global_action_voice_assist" msgid="7751191495200504480">"Isisekeli sezwi"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Khiya manje"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
- <!-- no translation found for notification_hidden_text (6351207030447943784) -->
- <skip />
+ <string name="notification_hidden_text" msgid="6351207030447943784">"Isaziso esisha"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Ikhibhodi ebonakalayo"</string>
<string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Ikhibhodi ephathekayo"</string>
<string name="notification_channel_security" msgid="7345516133431326347">"Ukuphepha"</string>
@@ -1176,8 +1177,8 @@
<string name="usb_midi_notification_title" msgid="4850904915889144654">"I-USB ye-MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ixhunywe ku-accessory ye-USB"</string>
<string name="usb_notification_message" msgid="3370903770828407960">"Thepha ngezinketho eziningi."</string>
- <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Insiza yomsindo ayisekelwa"</string>
- <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Thepha ngolwazi olungeziwe"</string>
+ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Kutholwe isisetshenziswa se-analog yomsindo"</string>
+ <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Idivayisi enamathiselwe kwi-imeyili ayihambisani nale foni. Thepha ukuze ufunde kabanzi."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Thepha ukuze ukhubaze ukususa isiphazamisi se-USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 733878b..7b26cf2 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -47,6 +47,10 @@
<item>@drawable/ic_clear_material</item>
<item>@drawable/ic_dialog_alert_material</item>
<item>@drawable/ic_go_search_api_material</item>
+ <item>@drawable/ic_media_route_connecting_dark_material</item>
+ <item>@drawable/ic_media_route_connecting_light_material</item>
+ <item>@drawable/ic_media_route_dark_material</item>
+ <item>@drawable/ic_media_route_light_material</item>
<item>@drawable/ic_menu_copy_material</item>
<item>@drawable/ic_menu_cut_material</item>
<item>@drawable/ic_menu_moreoverflow_material</item>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 33f69b4..3396728 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -561,19 +561,19 @@
to be set for all windows of this activity -->
<attr name="showForAllUsers" format="boolean" />
- <!-- Specifies whether an {@link Activity} should be shown on top of the the lock screen
+ <!-- Specifies whether an {@link android.app.Activity} should be shown on top of the the lock screen
whenever the lockscreen is up and the activity is resumed. Normally an activity will be
transitioned to the stopped state if it is started while the lockscreen is up, but with
this flag set the activity will remain in the resumed state visible on-top of the lock
screen.
- <p>This should be used instead of {@link android.view.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
+ <p>This should be used instead of {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
flag set for Windows. When using the Window flag during activity startup, there may not be
time to add it before the system stops your activity for being behind the lock-screen.
This leads to a double life-cycle as it is then restarted.</p> -->
<attr name="showWhenLocked" format="boolean" />
- <!-- Specifies whether the screen should be turned on when the {@link Activity} is resumed.
+ <!-- Specifies whether the screen should be turned on when the {@link android.app.Activity} is resumed.
Normally an activity will be transitioned to the stopped state if it is started while the
screen if off, but with this flag set the activity will cause the screen to turn on if the
activity will be visible and resumed due to the screen coming on. The screen will not be
@@ -581,10 +581,10 @@
normally used in conjunction with the {@link android.R.attr#showWhenLocked} flag to make
sure the activity is visible after the screen is turned on when the lockscreen is up. In
addition, if this flag is set and the activity calls
- {@link KeyguardManager#requestDismissKeyguard(Activity, KeyguardManager.KeyguardDismissCallback)}
+ {@link android.app.KeyguardManager#requestDismissKeyguard}
the screen will turn on.
- <p>This should be used instead of {@link android.view.LayoutParams.FLAG_TURN_SCREEN_ON}
+ <p>This should be used instead of {@link android.view.WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON}
flag set for Windows. When using the Window flag during activity startup, there may not be
time to add it before the system stops your activity because the screen has not yet turned
on. This leads to a double life-cycle as it is then restarted.</p> -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 536906c..fd78500 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -167,7 +167,7 @@
<color name="user_icon_default_white">#ffffffff</color><!-- white -->
<!-- Default profile badge colors -->
- <color name="profile_badge_1">#ffff5722</color><!-- Orange -->
+ <color name="profile_badge_1">#ffff6d00</color><!-- Orange -->
<color name="profile_badge_2">#ff000000</color><!-- Black -->
<color name="profile_badge_3">#ff22f033</color><!-- Green -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 27d55ba..961d639 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -525,6 +525,9 @@
<!-- Integers specifying the max packet Tx/Rx rates for full scan -->
<integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
<integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
+ <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
+ <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
+ <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
<!-- Integer parameters of the wifi to cellular handover feature
wifi should not stick to bad networks -->
<integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
@@ -603,10 +606,6 @@
during voice calls -->
<bool translatable="false" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit">false</bool>
- <!-- Integer indicating the value that framework needs to set the tx power to for meeting SAR requirements
- during voice calls -->
- <integer translatable="false" name="config_wifi_framework_voice_call_sar_tx_power_limit_in_dbm">0</integer>
-
<!-- Wifi driver supports batched scan -->
<bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
@@ -1392,6 +1391,7 @@
<!-- The package name of the default network recommendation app.
A network recommendation provider must:
* Be granted the SCORE_NETWORKS permission.
+ * Be granted the ACCESS_COARSE_LOCATION permission.
* Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action
protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission.
@@ -1677,6 +1677,10 @@
The size of the WAL file is also constrained by 'db_journal_size_limit'. -->
<integer name="db_wal_autocheckpoint">100</integer>
+ <!-- The number of milliseconds that SQLite connection is allowed to be idle before it
+ is closed and removed from the pool -->
+ <integer name="db_default_idle_connection_timeout">30000</integer>
+
<!-- Max space (in MB) allocated to DownloadManager to store the downloaded
files if they are to be stored in DownloadManager's data dir,
which typically is /data/data/com.android.providers.downloads/files -->
@@ -1889,10 +1893,12 @@
states. -->
<bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>
- <!-- Whether the display hardware requires we go to the off state before transitioning
- out of any doze states. -->
- <bool name="config_displayTransitionOffAfterDoze">false</bool>
+ <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
+ <bool name="config_displayBlanksAfterDoze">false</bool>
+ <!-- True if the display hardware only has brightness buckets rather than a full range of
+ backlight values -->
+ <bool name="config_displayBrightnessBucketsInDoze">false</bool>
<!-- Power Management: Specifies whether to decouple the auto-suspend state of the
device from the display on/off state.
@@ -3033,4 +3039,7 @@
<!-- Enable the RingtonePickerActivity in 'com.android.providers.media'. -->
<bool name="config_defaultRingtonePickerEnabled">true</bool>
+
+ <!-- Allow SystemUI to show the shutdown dialog -->
+ <bool name="config_showSysuiShutdown">true</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4b34402..8a5625b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -153,6 +153,10 @@
<string name="NetworkPreferenceSwitchTitle">Can\u2019t reach network</string>
<!-- Displayed to tell the user that they should switch their network preference. -->
<string name="NetworkPreferenceSwitchSummary">To improve reception, try changing the type selected at Settings > Network & Internet > Mobile networks > Preferred network type."</string>
+ <!-- Displayed to tell the user that emergency calls might not be available. -->
+ <string name="EmergencyCallWarningTitle">Wi\u2011Fi calling is active</string>
+ <!-- Displayed to tell the user that emergency calls might not be available. -->
+ <string name="EmergencyCallWarningSummary">Emergency calls require a mobile network.</string>
<!-- Telephony notification channel name for a channel containing network alert notifications. -->
<string name="notification_channel_network_alert">Alerts</string>
@@ -160,8 +164,8 @@
<string name="notification_channel_call_forward">Call forwarding</string>
<!-- Telephony notification channel name for a channel containing emergency callback mode notifications. -->
<string name="notification_channel_emergency_callback">Emergency callback mode</string>
- <!-- Telephony notification channel name for a channel containing mobile data alert notifications. -->
- <string name="notification_channel_mobile_data_alert">Mobile data alerts</string>
+ <!-- Telephony notification channel name for a channel containing mobile data status notifications. -->
+ <string name="notification_channel_mobile_data_status">Mobile data status</string>
<!-- Telephony notification channel name for a channel containing sms notifications. -->
<string name="notification_channel_sms">SMS messages</string>
<!-- Telephony notification channel name for a channel containing voice mail notifications. -->
@@ -218,7 +222,7 @@
</string-array>
<!-- WFC Operator Error Messages showed as notifications -->
<string-array name="wfcOperatorErrorNotificationMessages">
- <item>Register with your carrier</item>
+ <item>Register with your carrier (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
</string-array>
<!-- Template for showing mobile network operator name while WFC is active -->
<string-array name="wfcSpnFormats">
@@ -3131,9 +3135,9 @@
<!-- See USB_PREFERENCES. This is the message. -->
<string name="usb_notification_message">Tap for more options.</string>
<!-- USB_PREFERENCES: Notification for when a type-c USB audio accessory is attached but not supported. This is the title -->
- <string name="usb_unsupported_audio_accessory_title">Audio accessory not supported</string>
+ <string name="usb_unsupported_audio_accessory_title">Analog audio accessory detected</string>
<!-- Message of notification shown when a type-c USB audio accessory is attached but not supported. -->
- <string name="usb_unsupported_audio_accessory_message">Tap for more info</string>
+ <string name="usb_unsupported_audio_accessory_message">The attached device is not compatible with this phone. Tap to learn more.</string>
<!-- Title of notification shown when ADB is actively connected to the phone. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 4b0fe3f..e14aa14 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1493,6 +1493,12 @@
<item name="background">@drawable/autofill_dataset_picker_background</item>
</style>
+ <!-- @hide -->
+ <style name="AutofillSaveAnimation">
+ <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
+ <item name="android:windowExitAnimation">@anim/slide_out_down</item>
+ </style>
+
<!-- The style for the container of media actions in a notification. -->
<!-- @hide -->
<style name="NotificationMediaActionContainer">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a8aba0b..6042234 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -315,7 +315,6 @@
<java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
<java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
<java-symbol type="bool" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit" />
- <java-symbol type="integer" name="config_wifi_framework_voice_call_sar_tx_power_limit_in_dbm" />
<java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
<java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
<java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
@@ -378,6 +377,8 @@
<java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" />
<java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
<java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
+ <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
+ <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
<java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
<java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
@@ -429,6 +430,7 @@
<java-symbol type="integer" name="db_connection_pool_size" />
<java-symbol type="integer" name="db_journal_size_limit" />
<java-symbol type="integer" name="db_wal_autocheckpoint" />
+ <java-symbol type="integer" name="db_default_idle_connection_timeout" />
<java-symbol type="integer" name="config_soundEffectVolumeDb" />
<java-symbol type="integer" name="config_lockSoundVolumeDb" />
<java-symbol type="integer" name="config_multiuserMaximumUsers" />
@@ -530,6 +532,8 @@
<java-symbol type="string" name="PwdMmi" />
<java-symbol type="string" name="NetworkPreferenceSwitchSummary" />
<java-symbol type="string" name="NetworkPreferenceSwitchTitle" />
+ <java-symbol type="string" name="EmergencyCallWarningTitle" />
+ <java-symbol type="string" name="EmergencyCallWarningSummary" />
<java-symbol type="string" name="RestrictedOnAllVoiceTitle" />
<java-symbol type="string" name="RestrictedOnDataTitle" />
<java-symbol type="string" name="RestrictedOnEmergencyTitle" />
@@ -538,7 +542,7 @@
<java-symbol type="string" name="notification_channel_network_alert" />
<java-symbol type="string" name="notification_channel_call_forward" />
<java-symbol type="string" name="notification_channel_emergency_callback" />
- <java-symbol type="string" name="notification_channel_mobile_data_alert" />
+ <java-symbol type="string" name="notification_channel_mobile_data_status" />
<java-symbol type="string" name="notification_channel_sms" />
<java-symbol type="string" name="notification_channel_voice_mail" />
<java-symbol type="string" name="notification_channel_wfc" />
@@ -1302,10 +1306,8 @@
<java-symbol type="drawable" name="unlock_wave" />
<java-symbol type="drawable" name="notification_template_icon_bg" />
<java-symbol type="drawable" name="notification_template_icon_low_bg" />
- <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
<java-symbol type="drawable" name="ic_media_route_off_holo_dark" />
- <java-symbol type="drawable" name="ic_media_route_connecting_holo_dark" />
- <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
+ <java-symbol type="drawable" name="ic_media_route_off_holo_light" />
<java-symbol type="drawable" name="cling_button" />
<java-symbol type="drawable" name="cling_arrow_up" />
<java-symbol type="drawable" name="cling_bg" />
@@ -2919,6 +2921,7 @@
<java-symbol type="string" name="autofill_save_type_email_address" />
<java-symbol type="drawable" name="autofill_dataset_picker_background" />
<java-symbol type="style" name="AutofillDatasetPicker" />
+ <java-symbol type="style" name="AutofillSaveAnimation" />
<java-symbol type="dimen" name="autofill_dataset_picker_max_size"/>
<java-symbol type="dimen" name="autofill_save_custom_subtitle_max_height"/>
@@ -3039,7 +3042,8 @@
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
<java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
- <java-symbol type="bool" name="config_displayTransitionOffAfterDoze" />
+ <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
+ <java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
<java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
<java-symbol type="string" name="config_headlineFontFamily" />
<java-symbol type="string" name="config_headlineFontFamilyLight" />
@@ -3055,4 +3059,5 @@
<java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
<java-symbol type="layout" name="shutdown_dialog" />
<java-symbol type="dimen" name="chooser_service_spacing" />
+ <java-symbol type="bool" name="config_showSysuiShutdown" />
</resources>
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java
index ee40c48..29b6fd0 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java
@@ -28,7 +28,9 @@
import java.lang.reflect.Constructor;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.junit.After;
import org.junit.Before;
@@ -291,6 +293,7 @@
assertEquals(RadioManager.STATUS_OK, ret);
assertNotNull(info[0]);
assertEquals(channel, info[0].getChannel());
+ Log.d(TAG, "PI: " + info[0].toString());
}
@Test
@@ -344,7 +347,9 @@
openTuner();
try {
- List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(null);
+ Map<String, String> filter = new HashMap<>();
+ filter.put("com.google.dummy", "dummy");
+ List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(filter);
assertNotNull(list);
} catch (IllegalStateException e) {
// the list may or may not be ready at this point
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index e127896..ab9912a 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -978,6 +978,13 @@
</intent-filter>
</activity>
+ <activity android:name="android.view.ViewTransientState" android:label="View Transient State">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
<activity android:name="android.view.RemoteViewsActivity" android:label="RemoteViewsActicity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
index 4b01736..2c430e0 100644
--- a/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
+++ b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
@@ -40,15 +40,31 @@
<application
android:hasCode="true">
+ <meta-data android:name="key1" android:value="value1" />
+ <meta-data android:name="key2" android:value="this_is_app" />
+
<activity
android:name="com.android.frameworks.coretests.TestActivity">
+ <meta-data android:name="key1" android:value="value1" />
+ <meta-data android:name="key2" android:value="this_is_activity" />
</activity>
<provider
android:name="com.android.frameworks.coretests.TestProvider"
- android:authorities="com.android.frameworks.coretests.testprovider" />
+ android:authorities="com.android.frameworks.coretests.testprovider" >
+ <meta-data android:name="key1" android:value="value1" />
+ <meta-data android:name="key2" android:value="this_is_provider" />
+ </provider>
+
<receiver
- android:name="com.android.frameworks.coretests.TestReceiver" />
+ android:name="com.android.frameworks.coretests.TestReceiver" >
+ <meta-data android:name="key1" android:value="value1" />
+ <meta-data android:name="key2" android:value="this_is_receiver" />
+ </receiver>
+
<service
- android:name="com.android.frameworks.coretests.TestService" />
+ android:name="com.android.frameworks.coretests.TestService" >
+ <meta-data android:name="key1" android:value="value1" />
+ <meta-data android:name="key2" android:value="this_is_service" />
+ </service>
</application>
</manifest>
diff --git a/core/tests/coretests/assets/fonts/a3em.ttf b/core/tests/coretests/assets/fonts/a3em.ttf
deleted file mode 100644
index a601ce2..0000000
--- a/core/tests/coretests/assets/fonts/a3em.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/a3em.ttx b/core/tests/coretests/assets/fonts/a3em.ttx
deleted file mode 100644
index d3b9e16..0000000
--- a/core/tests/coretests/assets/fonts/a3em.ttx
+++ /dev/null
@@ -1,187 +0,0 @@
-<?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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="3em" />
- <map code="0x0062" name="1em" />
- <map code="0x0063" name="1em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/assets/fonts/all2em.ttf b/core/tests/coretests/assets/fonts/all2em.ttf
deleted file mode 100644
index 482f755..0000000
--- a/core/tests/coretests/assets/fonts/all2em.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/all2em.ttx b/core/tests/coretests/assets/fonts/all2em.ttx
deleted file mode 100644
index fe95ff0..0000000
--- a/core/tests/coretests/assets/fonts/all2em.ttx
+++ /dev/null
@@ -1,184 +0,0 @@
-<?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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="2em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="2em" width="1000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="2em" />
- <map code="0x0062" name="2em" />
- <map code="0x0063" name="2em" />
- <map code="0x0064" name="2em" />
- <map code="0x0065" name="2em" />
- </cmap_format_4>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="2em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/assets/fonts/b3em.ttf b/core/tests/coretests/assets/fonts/b3em.ttf
deleted file mode 100644
index 63948a2..0000000
--- a/core/tests/coretests/assets/fonts/b3em.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/b3em.ttx b/core/tests/coretests/assets/fonts/b3em.ttx
deleted file mode 100644
index b5a77ef..0000000
--- a/core/tests/coretests/assets/fonts/b3em.ttx
+++ /dev/null
@@ -1,187 +0,0 @@
-<?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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="1em" />
- <map code="0x0062" name="3em" />
- <map code="0x0063" name="1em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/assets/fonts/c3em.ttf b/core/tests/coretests/assets/fonts/c3em.ttf
deleted file mode 100644
index badc3e2..0000000
--- a/core/tests/coretests/assets/fonts/c3em.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/c3em.ttx b/core/tests/coretests/assets/fonts/c3em.ttx
deleted file mode 100644
index f5ed8e5..0000000
--- a/core/tests/coretests/assets/fonts/c3em.ttx
+++ /dev/null
@@ -1,187 +0,0 @@
-<?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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="1em" />
- <map code="0x0062" name="1em" />
- <map code="0x0063" name="3em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/assets/fonts/no_coverage.ttf b/core/tests/coretests/assets/fonts/no_coverage.ttf
deleted file mode 100644
index c884881..0000000
--- a/core/tests/coretests/assets/fonts/no_coverage.ttf
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/no_coverage.ttx b/core/tests/coretests/assets/fonts/no_coverage.ttx
deleted file mode 100644
index 3be5f86..0000000
--- a/core/tests/coretests/assets/fonts/no_coverage.ttx
+++ /dev/null
@@ -1,180 +0,0 @@
-<?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.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="dummy"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="dummy" width="500" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0xFFFD" name="dummy" /> <!-- dummy entry -->
- </cmap_format_4>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="dummy" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/core/tests/coretests/res/layout/view_transient_state.xml b/core/tests/coretests/res/layout/view_transient_state.xml
new file mode 100644
index 0000000..8873015
--- /dev/null
+++ b/core/tests/coretests/res/layout/view_transient_state.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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.
+*/
+-->
+
+<!-- Demonstrates view transient state, See corresponding Java code. -->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <FrameLayout
+ android:id="@+id/p1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <FrameLayout
+ android:id="@+id/p2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/p3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ </TextView>
+
+ </FrameLayout>
+
+ </FrameLayout>
+
+</FrameLayout>
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserCacheHelperTest.java b/core/tests/coretests/src/android/content/pm/PackageParserCacheHelperTest.java
new file mode 100644
index 0000000..00be822
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/PackageParserCacheHelperTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.content.pm;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.pm.PackageParserCacheHelper.ReadHelper;
+import android.content.pm.PackageParserCacheHelper.WriteHelper;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PackageParserCacheHelperTest {
+ @Test
+ public void testParcelUnparcel() throws Exception {
+ final Bundle source = new Bundle();
+ source.putInt("i1", 123);
+ source.putString("s1", "abcdef");
+ source.putString("s2", "xyz");
+ source.putString("s3", null);
+
+ final Bundle nest = new Bundle();
+ nest.putString("s1", "xyz");
+ source.putBundle("b1", nest);
+
+ final Parcel p = Parcel.obtain();
+ final WriteHelper writeHelper = new WriteHelper(p);
+
+ source.writeToParcel(p, 0);
+ writeHelper.finishAndUninstall();
+
+ p.setDataPosition(0);
+
+ final ReadHelper readHelper = new ReadHelper(p);
+ readHelper.startAndInstall();
+
+ final Bundle dest = new Bundle();
+ dest.readFromParcel(p);
+
+ dest.size(); // Unparcel so that toString() returns the content.
+
+ assertEquals(source.get("i1"), dest.get("i1"));
+ assertEquals(source.get("s1"), dest.get("s1"));
+ assertEquals(source.get("s2"), dest.get("s2"));
+ assertEquals(source.get("s3"), dest.get("s3"));
+ assertEquals(source.getBundle("b1").get("s1"), dest.getBundle("b1").get("s1"));
+ assertEquals(source.keySet().size(), dest.keySet().size());
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index 73c153f..fda0f1e 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.Permission;
import android.os.Build;
+import android.os.Bundle;
import android.os.FileUtils;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
@@ -39,6 +40,7 @@
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
+import java.util.function.Function;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -271,22 +273,27 @@
assertEquals(0x0083, finalConfigChanges); // Should be 10000011.
}
+ Package parsePackage(String apkFileName, int apkResourceId) throws Exception {
+ return parsePackage(apkFileName, apkResourceId, p -> p);
+ }
+
/**
* Attempts to parse a package.
*
* APKs are put into coretests/apks/packageparser_*.
*
- * @param apkName temporary file name to store apk extracted from resources
+ * @param apkFileName temporary file name to store apk extracted from resources
* @param apkResourceId identifier of the apk as a resource
*/
- Package parsePackage(String apkFileName, int apkResourceId) throws Exception {
+ Package parsePackage(String apkFileName, int apkResourceId,
+ Function<Package, Package> converter) throws Exception {
// Copy the resource to a file.
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
File outFile = new File(context.getFilesDir(), apkFileName);
try {
InputStream is = context.getResources().openRawResource(apkResourceId);
assertTrue(FileUtils.copyToFile(is, outFile));
- return new PackageParser().parsePackage(outFile, 0 /* flags */);
+ return converter.apply(new PackageParser().parsePackage(outFile, 0 /* flags */));
} finally {
outFile.delete();
}
@@ -331,10 +338,39 @@
assertEquals(protectionLevel, permission.info.protectionLevel);
}
+ private void assertMetadata(Bundle b, String... keysAndValues) {
+ assertTrue("Odd number of elements in keysAndValues", (keysAndValues.length % 2) == 0);
+
+ assertNotNull(b);
+ assertEquals(keysAndValues.length / 2, b.size());
+
+ for (int i = 0; i < keysAndValues.length; i += 2) {
+ final String key = keysAndValues[i];
+ final String value = keysAndValues[i + 1];
+
+ assertEquals(value, b.getString(key));
+ }
+ }
+
+ // TODO Add a "_cached" test for testMultiPackageComponents() too, after fixing b/64295061.
+ // Package.writeToParcel can't handle circular package references.
+
@Test
- public void testPackageWithComponents() throws Exception {
+ public void testPackageWithComponents_no_cache() throws Exception {
+ checkPackageWithComponents(p -> p);
+ }
+
+ @Test
+ public void testPackageWithComponents_cached() throws Exception {
+ checkPackageWithComponents(p ->
+ PackageParser.fromCacheEntryStatic(PackageParser.toCacheEntryStatic(p)));
+ }
+
+ private void checkPackageWithComponents(
+ Function<Package, Package> converter) throws Exception {
Package p = parsePackage(
- "install_complete_package_info.apk", R.raw.install_complete_package_info);
+ "install_complete_package_info.apk", R.raw.install_complete_package_info,
+ converter);
String packageName = "com.android.frameworks.coretests.install_complete_package_info";
assertEquals(packageName, p.packageName);
@@ -344,6 +380,22 @@
packageName, PermissionInfo.PROTECTION_NORMAL, p.permissions.get(0));
assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p);
+
+ assertMetadata(p.mAppMetaData,
+ "key1", "value1",
+ "key2", "this_is_app");
+ assertMetadata(p.activities.get(0).metaData,
+ "key1", "value1",
+ "key2", "this_is_activity");
+ assertMetadata(p.services.get(0).metaData,
+ "key1", "value1",
+ "key2", "this_is_service");
+ assertMetadata(p.receivers.get(0).metaData,
+ "key1", "value1",
+ "key2", "this_is_receiver");
+ assertMetadata(p.providers.get(0).metaData,
+ "key1", "value1",
+ "key2", "this_is_provider");
}
@Test
diff --git a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
index 7800f4a..335cea7 100644
--- a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
@@ -25,6 +25,8 @@
import android.database.sqlite.SQLiteDebug;
import android.database.sqlite.SQLiteException;
import android.os.Parcel;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.UiDevice;
import android.test.AndroidTestCase;
import android.test.PerformanceTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -1056,7 +1058,7 @@
mDatabase.close();
SQLiteDatabase.OpenParams params = new SQLiteDatabase.OpenParams.Builder()
.setLookasideConfig(0, 0).build();
- mDatabase = SQLiteDatabase.openDatabase(mDatabaseFile.getPath(), params);
+ mDatabase = SQLiteDatabase.openDatabase(mDatabaseFile, params);
verifyLookasideStats(true);
}
@@ -1185,4 +1187,38 @@
fail("unexpected");
}
}
+
+ @MediumTest
+ public void testCloseIdleConnection() throws Exception {
+ mDatabase.close();
+ SQLiteDatabase.OpenParams params = new SQLiteDatabase.OpenParams.Builder()
+ .setIdleConnectionTimeout(1000).build();
+ mDatabase = SQLiteDatabase.openDatabase(mDatabaseFile, params);
+ // Wait a bit and check that connection is still open
+ Thread.sleep(100);
+ String output = executeShellCommand("dumpsys dbinfo " + getContext().getPackageName());
+ assertTrue("Connection #0 should be open. Output: " + output,
+ output.contains("Connection #0:"));
+
+ // Now cause idle timeout and check that connection is closed
+ Thread.sleep(1000);
+ output = executeShellCommand("dumpsys dbinfo " + getContext().getPackageName());
+ assertFalse("Connection #0 should be closed. Output: " + output,
+ output.contains("Connection #0:"));
+ }
+
+ @SmallTest
+ public void testSetIdleConnectionTimeoutValidation() throws Exception {
+ try {
+ new SQLiteDatabase.OpenParams.Builder().setIdleConnectionTimeout(-1).build();
+ fail("Negative timeout should be rejected");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private String executeShellCommand(String cmd) throws Exception {
+ return UiDevice.getInstance(
+ InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
+ }
+
}
diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
deleted file mode 100644
index ca4f7d4..0000000
--- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
+++ /dev/null
@@ -1,469 +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.
- */
-
-package android.graphics;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.ArrayMap;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TypefaceSystemFallbackTest {
- private static final String SYSTEM_FONT_DIR = "/system/fonts/";
- private static final String SYSTEM_FONTS_XML = "/system/etc/fonts.xml";
-
- private static final String[] TEST_FONT_FILES = {
- "a3em.ttf", // Supports "a","b","c". The width of "a" is 3em, others are 1em.
- "b3em.ttf", // Supports "a","b","c". The width of "b" is 3em, others are 1em.
- "c3em.ttf", // Supports "a","b","c". The width of "c" is 3em, others are 1em.
- "all2em.ttf", // Supports "a,","b","c". All of them have the same width of 2em.
- "no_coverage.ttf", // This font doesn't support any characters.
- };
- private static final String TEST_FONTS_XML;
- private static final String TEST_FONT_DIR;
-
- private static final float GLYPH_1EM_WIDTH;
- private static final float GLYPH_2EM_WIDTH;
- private static final float GLYPH_3EM_WIDTH;
-
- static {
- final Context targetCtx = InstrumentationRegistry.getInstrumentation().getTargetContext();
- final File cacheDir = new File(targetCtx.getCacheDir(), "TypefaceSystemFallbackTest");
- if (!cacheDir.isDirectory()) {
- cacheDir.mkdirs();
- }
- TEST_FONT_DIR = cacheDir.getAbsolutePath() + "/";
- TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath();
-
- final AssetManager am =
- InstrumentationRegistry.getInstrumentation().getContext().getAssets();
- final Paint paint = new Paint();
- paint.setTypeface(new Typeface.Builder(am, "fonts/a3em.ttf").build());
- GLYPH_3EM_WIDTH = paint.measureText("a");
- GLYPH_1EM_WIDTH = paint.measureText("b");
-
- paint.setTypeface(new Typeface.Builder(am, "fonts/all2em.ttf").build());
- GLYPH_2EM_WIDTH = paint.measureText("a");
- }
-
- @Before
- public void setUp() {
- final AssetManager am =
- InstrumentationRegistry.getInstrumentation().getContext().getAssets();
- for (final String fontFile : TEST_FONT_FILES) {
- final String sourceInAsset = "fonts/" + fontFile;
- final File outInCache = new File(TEST_FONT_DIR, fontFile);
- try (InputStream is = am.open(sourceInAsset)) {
- Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- @After
- public void tearDown() {
- for (final String fontFile : TEST_FONT_FILES) {
- final File outInCache = new File(TEST_FONT_DIR, fontFile);
- outInCache.delete();
- }
- }
-
- private static void buildSystemFallback(String xml,
- ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
- try (FileOutputStream fos = new FileOutputStream(TEST_FONTS_XML)) {
- fos.write(xml.getBytes(Charset.forName("UTF-8")));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- Typeface.buildSystemFallback(TEST_FONTS_XML, TEST_FONT_DIR, fontMap, fallbackMap);
- }
-
- @Test
- public void testBuildSystemFallback() {
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- Typeface.buildSystemFallback(SYSTEM_FONTS_XML, SYSTEM_FONT_DIR, fontMap, fallbackMap);
-
- assertFalse(fontMap.isEmpty());
- assertFalse(fallbackMap.isEmpty());
- }
-
- @Test
- public void testBuildSystemFallback_NonExistentFontShouldBeIgnored() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + " <family name='NoSuchFont'>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- assertEquals(1, fontMap.size());
- assertTrue(fontMap.containsKey("sans-serif"));
- assertEquals(1, fallbackMap.size());
- assertTrue(fallbackMap.containsKey("sans-serif"));
- }
-
- @Test
- public void testBuildSystemFallback_NamedFamily() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>c3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_defaultFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_namedFallbackFamily() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test2'>b3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_namedFallbackFamily2() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ImplicitSansSerifFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ElegantFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family variant='elegant'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family variant='compact'>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface testTypeface = fontMap.get("serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ElegantFallback_customFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family variant='elegant'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " <font weight='400' style='normal' fallbackFor='serif'>b3em.ttf</font>"
- + " </family>"
- + " <family variant='compact'>"
- + " <font weight='400' style='normal'>c3em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- Typeface testTypeface = fontMap.get("serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
-
- testTypeface = fontMap.get("sans-serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-}
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
new file mode 100644
index 0000000..9fcf96d
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for bundle that requires accessing hidden APS. Tests that can be written only with
+ * public APIs should go in the CTS counterpart.
+ *
+ * Run with:
+ * bit FrameworksCoreTests:android.os.BundleTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BundleTest {
+ /**
+ * Create a test bundle, parcel it and return the parcel.
+ */
+ private Parcel createBundleParcel(boolean withFd) throws Exception {
+ final Bundle source = new Bundle();
+ source.putString("string", "abc");
+ source.putInt("int", 1);
+ if (withFd) {
+ ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+ pipe[1].close();
+ source.putParcelable("fd", pipe[0]);
+ }
+ final Parcel p = Parcel.obtain();
+ // Don't use p.writeParcelabe(), which would write the creator, which we don't need.
+ source.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ return p;
+ }
+
+ /**
+ * Verify a bundle generated by {@link #createBundleParcel(boolean)}.
+ */
+ private void checkBundle(Bundle b, boolean withFd) {
+ // First, do the checks without actually unparceling the bundle.
+ // (Note looking into the contents will unparcel a bundle, so we'll do it later.)
+ assertTrue("mParcelledData shouldn't be null here.", b.isParcelled());
+
+ // Make sure FLAG_HAS_FDS and FLAG_HAS_FDS_KNOWN are set/cleared properly.
+ if (withFd) {
+ // FLAG_HAS_FDS and FLAG_HAS_FDS_KNOWN should both be set.
+ assertEquals(Bundle.FLAG_HAS_FDS | Bundle.FLAG_HAS_FDS_KNOWN,
+ b.mFlags & (Bundle.FLAG_HAS_FDS | Bundle.FLAG_HAS_FDS_KNOWN));
+ } else {
+ // FLAG_HAS_FDS_KNOWN should be set, bot not FLAG_HAS_FDS.
+ assertEquals(Bundle.FLAG_HAS_FDS_KNOWN,
+ b.mFlags & (Bundle.FLAG_HAS_FDS | Bundle.FLAG_HAS_FDS_KNOWN));
+ }
+
+ // Then, check the contents.
+ assertEquals("abc", b.getString("string"));
+ assertEquals(1, b.getInt("int"));
+
+ // Make sure FLAG_HAS_FDS and FLAG_HAS_FDS_KNOWN are set/cleared properly.
+ if (withFd) {
+ assertEquals(ParcelFileDescriptor.class, b.getParcelable("fd").getClass());
+ assertEquals(3, b.keySet().size());
+ } else {
+ assertEquals(2, b.keySet().size());
+ }
+ assertFalse(b.isParcelled());
+ }
+
+ @Test
+ public void testCreateFromParcel() throws Exception {
+ boolean withFd;
+ Parcel p;
+ Bundle b;
+ int length;
+
+ withFd = false;
+
+ // new Bundle with p
+ p = createBundleParcel(withFd);
+ checkBundle(new Bundle(p), withFd);
+ p.recycle();
+
+ // new Bundle with p and length
+ p = createBundleParcel(withFd);
+ length = p.readInt();
+ checkBundle(new Bundle(p, length), withFd);
+ p.recycle();
+
+ // readFromParcel()
+ p = createBundleParcel(withFd);
+ b = new Bundle();
+ b.readFromParcel(p);
+ checkBundle(b, withFd);
+ p.recycle();
+
+ // Same test with FDs.
+ withFd = true;
+
+ // new Bundle with p
+ p = createBundleParcel(withFd);
+ checkBundle(new Bundle(p), withFd);
+ p.recycle();
+
+ // new Bundle with p and length
+ p = createBundleParcel(withFd);
+ length = p.readInt();
+ checkBundle(new Bundle(p, length), withFd);
+ p.recycle();
+
+ // readFromParcel()
+ p = createBundleParcel(withFd);
+ b = new Bundle();
+ b.readFromParcel(p);
+ checkBundle(b, withFd);
+ p.recycle();
+ }
+}
diff --git a/core/tests/coretests/src/android/view/ViewTransientState.java b/core/tests/coretests/src/android/view/ViewTransientState.java
new file mode 100644
index 0000000..206ff81
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewTransientState.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.frameworks.coretests.R;
+
+/**
+ * Exercise set View's transient state
+ */
+public class ViewTransientState extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.view_transient_state);
+ }
+}
diff --git a/core/tests/coretests/src/android/view/ViewTransientStateTest.java b/core/tests/coretests/src/android/view/ViewTransientStateTest.java
new file mode 100644
index 0000000..36ea01d
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewTransientStateTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.view;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.frameworks.coretests.R;
+
+import static org.junit.Assert.assertFalse;
+
+/**
+ * Exercise set View's transient state
+ */
+public class ViewTransientStateTest extends ActivityInstrumentationTestCase<ViewTransientState> {
+
+ View mP1;
+ View mP2;
+ View mP3;
+
+ public ViewTransientStateTest() {
+ super("com.android.frameworks.coretests", ViewTransientState.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final Activity a = getActivity();
+ mP1 = a.findViewById(R.id.p1);
+ mP2 = a.findViewById(R.id.p2);
+ mP3 = a.findViewById(R.id.p3);
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testSetTransientState1() throws Exception {
+ mP3.setHasTransientState(true);
+ mP2.setHasTransientState(true);
+ mP3.setHasTransientState(false);
+ mP2.setHasTransientState(false);
+ assertFalse(mP3.hasTransientState());
+ assertFalse(mP2.hasTransientState());
+ assertFalse(mP1.hasTransientState());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testSetTransientState2() throws Exception {
+ mP3.setHasTransientState(true);
+ mP2.setHasTransientState(true);
+ mP2.setHasTransientState(false);
+ mP3.setHasTransientState(false);
+ assertFalse(mP3.hasTransientState());
+ assertFalse(mP2.hasTransientState());
+ assertFalse(mP1.hasTransientState());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testSetTransientState3() throws Exception {
+ mP2.setHasTransientState(true);
+ mP3.setHasTransientState(true);
+ mP3.setHasTransientState(false);
+ mP2.setHasTransientState(false);
+ assertFalse(mP3.hasTransientState());
+ assertFalse(mP2.hasTransientState());
+ assertFalse(mP1.hasTransientState());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testSetTransientState4() throws Exception {
+ mP2.setHasTransientState(true);
+ mP3.setHasTransientState(true);
+ mP2.setHasTransientState(false);
+ mP3.setHasTransientState(false);
+ assertFalse(mP3.hasTransientState());
+ assertFalse(mP2.hasTransientState());
+ assertFalse(mP1.hasTransientState());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 29447ed..2a6c22e 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -32,9 +32,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.List;
-import java.util.Locale;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextClassificationManagerTest {
@@ -177,20 +174,6 @@
}
@Test
- public void testLanguageDetection() {
- if (isTextClassifierDisabled()) return;
-
- String text = "This is a piece of English text";
- assertThat(mTcm.detectLanguages(text), isDetectedLanguage("en"));
-
- text = "Das ist ein deutscher Text";
- assertThat(mTcm.detectLanguages(text), isDetectedLanguage("de"));
-
- text = "これは日本語のテキストです";
- assertThat(mTcm.detectLanguages(text), isDetectedLanguage("ja"));
- }
-
- @Test
public void testSetTextClassifier() {
TextClassifier classifier = mock(TextClassifier.class);
mTcm.setTextClassifier(classifier);
@@ -270,30 +253,4 @@
}
};
}
-
- private static Matcher<List<TextLanguage>> isDetectedLanguage(final String language) {
- return new BaseMatcher<List<TextLanguage>>() {
- @Override
- public boolean matches(Object o) {
- if (o instanceof List) {
- List languages = (List) o;
- if (!languages.isEmpty()) {
- Object o1 = languages.get(0);
- if (o1 instanceof TextLanguage) {
- TextLanguage lang = (TextLanguage) o1;
- return lang.getLanguageCount() > 0
- && new Locale(language).getLanguage()
- .equals(lang.getLanguage(0).getLanguage());
- }
- }
- }
- return false;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendValue(String.format("%s", language));
- }
- };
- }
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index 8fd4e31..0294095 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -488,7 +488,7 @@
bi.noteStartSensorLocked(UID, SENSOR_ID);
clocks.realtime += 111;
- clocks.uptime += 1111;
+ clocks.uptime += 111;
// Timebase and timer was on so times have increased.
assertEquals(111_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index 7fafef7..3a81c13 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -28,4 +28,6 @@
<backup-transport-whitelisted-service
service="android/com.android.internal.backup.LocalTransportService" />
+ <!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
+ <app-link package="com.android.carrierdefaultapp" />
</config>
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 80a9324..7c07a30 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -111,7 +111,6 @@
String weightStr = parser.getAttributeValue(null, "weight");
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
- String fallbackFor = parser.getAttributeValue(null, "fallbackFor");
StringBuilder filename = new StringBuilder();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() == XmlPullParser.TEXT) {
@@ -127,7 +126,7 @@
}
String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
return new FontConfig.Font(sanitizedName, index,
- axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor);
+ axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic);
}
private static FontVariationAxis readAxis(XmlPullParser parser)
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 1d8b583..c4b56c3 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -38,7 +38,6 @@
import android.provider.FontRequest;
import android.provider.FontsContract;
import android.text.FontConfig;
-import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;
import android.util.LongSparseArray;
@@ -46,7 +45,6 @@
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
@@ -107,10 +105,12 @@
private static final LruCache<String, Typeface> sDynamicTypefaceCache = new LruCache<>(16);
static Typeface sDefaultTypeface;
- static final Map<String, Typeface> sSystemFontMap;
- static final Map<String, FontFamily[]> sSystemFallbackMap;
+ static Map<String, Typeface> sSystemFontMap;
+ static FontFamily[] sFallbackFonts;
private static final Object sLock = new Object();
+ static final String FONTS_CONFIG = "fonts.xml";
+
/**
* @hide
*/
@@ -129,7 +129,6 @@
// Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
/** @hide */
public static final int RESOLVE_BY_FONT_TABLE = -1;
- private static final String DEFAULT_FAMILY = "sans-serif";
// Style value for building typeface.
private static final int STYLE_NORMAL = 0;
@@ -164,27 +163,28 @@
*/
@Nullable
public static Typeface createFromResources(AssetManager mgr, String path, int cookie) {
- synchronized (sDynamicTypefaceCache) {
- final String key = Builder.createAssetUid(
- mgr, path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */,
- DEFAULT_FAMILY);
- Typeface typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
+ if (sFallbackFonts != null) {
+ synchronized (sDynamicTypefaceCache) {
+ final String key = Builder.createAssetUid(
+ mgr, path, 0 /* ttcIndex */, null /* axes */,
+ RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
+ Typeface typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) return typeface;
- FontFamily fontFamily = new FontFamily();
- // TODO: introduce ttc index and variation settings to resource type font.
- if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
- 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
- RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
- if (!fontFamily.freeze()) {
- return null;
+ FontFamily fontFamily = new FontFamily();
+ // TODO: introduce ttc index and variation settings to resource type font.
+ if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
+ 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
+ RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
+ if (!fontFamily.freeze()) {
+ return null;
+ }
+ FontFamily[] families = {fontFamily};
+ typeface = createFromFamiliesWithDefault(families,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ sDynamicTypefaceCache.put(key, typeface);
+ return typeface;
}
- FontFamily[] families = {fontFamily};
- typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
}
}
return null;
@@ -197,57 +197,61 @@
@Nullable
public static Typeface createFromResources(
FamilyResourceEntry entry, AssetManager mgr, String path) {
- if (entry instanceof ProviderResourceEntry) {
- final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
- // Downloadable font
- List<List<String>> givenCerts = providerEntry.getCerts();
- List<List<byte[]>> certs = new ArrayList<>();
- if (givenCerts != null) {
- for (int i = 0; i < givenCerts.size(); i++) {
- List<String> certSet = givenCerts.get(i);
- List<byte[]> byteArraySet = new ArrayList<>();
- for (int j = 0; j < certSet.size(); j++) {
- byteArraySet.add(Base64.decode(certSet.get(j), Base64.DEFAULT));
+ if (sFallbackFonts != null) {
+ if (entry instanceof ProviderResourceEntry) {
+ final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
+ // Downloadable font
+ List<List<String>> givenCerts = providerEntry.getCerts();
+ List<List<byte[]>> certs = new ArrayList<>();
+ if (givenCerts != null) {
+ for (int i = 0; i < givenCerts.size(); i++) {
+ List<String> certSet = givenCerts.get(i);
+ List<byte[]> byteArraySet = new ArrayList<>();
+ for (int j = 0; j < certSet.size(); j++) {
+ byteArraySet.add(Base64.decode(certSet.get(j), Base64.DEFAULT));
+ }
+ certs.add(byteArraySet);
}
- certs.add(byteArraySet);
+ }
+ // Downloaded font and it wasn't cached, request it again and return a
+ // default font instead (nothing we can do now).
+ FontRequest request = new FontRequest(providerEntry.getAuthority(),
+ providerEntry.getPackage(), providerEntry.getQuery(), certs);
+ Typeface typeface = FontsContract.getFontSync(request);
+ return typeface == null ? DEFAULT : typeface;
+ }
+
+ Typeface typeface = findFromCache(mgr, path);
+ if (typeface != null) return typeface;
+
+ // family is FontFamilyFilesResourceEntry
+ final FontFamilyFilesResourceEntry filesEntry =
+ (FontFamilyFilesResourceEntry) entry;
+
+ FontFamily fontFamily = new FontFamily();
+ for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
+ // TODO: Add ttc and variation font support. (b/37853920)
+ if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
+ 0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
+ fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
+ return null;
}
}
- // Downloaded font and it wasn't cached, request it again and return a
- // default font instead (nothing we can do now).
- FontRequest request = new FontRequest(providerEntry.getAuthority(),
- providerEntry.getPackage(), providerEntry.getQuery(), certs);
- Typeface typeface = FontsContract.getFontSync(request);
- return typeface == null ? DEFAULT : typeface;
- }
-
- Typeface typeface = findFromCache(mgr, path);
- if (typeface != null) return typeface;
-
- // family is FontFamilyFilesResourceEntry
- final FontFamilyFilesResourceEntry filesEntry = (FontFamilyFilesResourceEntry) entry;
-
- FontFamily fontFamily = new FontFamily();
- for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
- // TODO: Add ttc and variation font support. (b/37853920)
- if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
- 0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
- fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
+ if (!fontFamily.freeze()) {
return null;
}
+ FontFamily[] familyChain = { fontFamily };
+ typeface = createFromFamiliesWithDefault(familyChain,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ synchronized (sDynamicTypefaceCache) {
+ final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
+ null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
+ RESOLVE_BY_FONT_TABLE /* italic */);
+ sDynamicTypefaceCache.put(key, typeface);
+ }
+ return typeface;
}
- if (!fontFamily.freeze()) {
- return null;
- }
- FontFamily[] familyChain = { fontFamily };
- typeface = createFromFamiliesWithDefault(familyChain, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- synchronized (sDynamicTypefaceCache) {
- final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
- null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
- RESOLVE_BY_FONT_TABLE /* italic */, DEFAULT_FAMILY);
- sDynamicTypefaceCache.put(key, typeface);
- }
- return typeface;
+ return null;
}
/**
@@ -257,8 +261,7 @@
public static Typeface findFromCache(AssetManager mgr, String path) {
synchronized (sDynamicTypefaceCache) {
final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */,
- DEFAULT_FAMILY);
+ RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
Typeface typeface = sDynamicTypefaceCache.get(key);
if (typeface != null) {
return typeface;
@@ -495,7 +498,7 @@
* @return Unique id for a given AssetManager and asset path.
*/
private static String createAssetUid(final AssetManager mgr, String path, int ttcIndex,
- @Nullable FontVariationAxis[] axes, int weight, int italic, String fallback) {
+ @Nullable FontVariationAxis[] axes, int weight, int italic) {
final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers();
final StringBuilder builder = new StringBuilder();
final int size = pkgs.size();
@@ -510,11 +513,7 @@
builder.append(Integer.toString(weight));
builder.append("-");
builder.append(Integer.toString(italic));
- // Family name may contain hyphen. Use double hyphen for avoiding key conflicts before
- // and after appending falblack name.
- builder.append("--");
- builder.append(fallback);
- builder.append("--");
+ builder.append("-");
if (axes != null) {
for (FontVariationAxis axis : axes) {
builder.append(axis.getTag());
@@ -594,15 +593,13 @@
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
} catch (IOException e) {
return resolveFallbackTypeface();
}
} else if (mAssetManager != null) { // Builder is created with asset manager.
final String key = createAssetUid(
- mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic,
- mFallbackFamilyName);
+ mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic);
synchronized (sLock) {
Typeface typeface = sDynamicTypefaceCache.get(key);
if (typeface != null) return typeface;
@@ -616,8 +613,7 @@
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- typeface = createFromFamiliesWithDefault(families, mFallbackFamilyName,
- mWeight, mItalic);
+ typeface = createFromFamiliesWithDefault(families, mWeight, mItalic);
sDynamicTypefaceCache.put(key, typeface);
return typeface;
}
@@ -631,8 +627,7 @@
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
} else if (mFonts != null) {
final FontFamily fontFamily = new FontFamily();
boolean atLeastOneFont = false;
@@ -658,8 +653,7 @@
}
fontFamily.freeze();
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
}
// Must not reach here.
@@ -679,7 +673,10 @@
* @return The best matching typeface.
*/
public static Typeface create(String familyName, int style) {
- return create(sSystemFontMap.get(familyName), style);
+ if (sSystemFontMap != null) {
+ return create(sSystemFontMap.get(familyName), style);
+ }
+ return null;
}
/**
@@ -754,33 +751,34 @@
if (path == null) {
throw new NullPointerException(); // for backward compatibility
}
- synchronized (sLock) {
- Typeface typeface = new Builder(mgr, path).build();
- if (typeface != null) return typeface;
+ if (sFallbackFonts != null) {
+ synchronized (sLock) {
+ Typeface typeface = new Builder(mgr, path).build();
+ if (typeface != null) return typeface;
- final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
- null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
- DEFAULT_FAMILY);
- typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
+ final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
+ null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) return typeface;
- final FontFamily fontFamily = new FontFamily();
- if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
- 0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
- null /* axes */)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback
- // font selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
- final FontFamily[] families = { fontFamily };
- typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
- } else {
- fontFamily.abortCreation();
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
+ 0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
+ null /* axes */)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback
+ // font selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ final FontFamily[] families = { fontFamily };
+ typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+ RESOLVE_BY_FONT_TABLE);
+ sDynamicTypefaceCache.put(key, typeface);
+ return typeface;
+ } else {
+ fontFamily.abortCreation();
+ }
}
}
throw new RuntimeException("Font asset not found " + path);
@@ -817,20 +815,22 @@
* @return The new typeface.
*/
public static Typeface createFromFile(@Nullable String path) {
- final FontFamily fontFamily = new FontFamily();
- if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback font
- // selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
- FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- } else {
- fontFamily.abortCreation();
+ if (sFallbackFonts != null) {
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback font
+ // selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ FontFamily[] families = { fontFamily };
+ return createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+ RESOLVE_BY_FONT_TABLE);
+ } else {
+ fontFamily.abortCreation();
+ }
}
throw new RuntimeException("Font not found " + path);
}
@@ -852,8 +852,6 @@
/**
* Create a new typeface from an array of font families, including
* also the font families in the fallback list.
- * @param fallbackName the family name. If given families don't support characters, the
- * characters will be rendered with this family.
* @param weight the weight for this family. {@link RESOLVE_BY_FONT_TABLE} can be used. In that
* case, the table information in the first family's font is used. If the first
* family has multiple fonts, the closest to the regular weight and upright font
@@ -865,17 +863,13 @@
* @param families array of font families
*/
private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
- String fallbackName, int weight, int italic) {
- FontFamily[] fallback = sSystemFallbackMap.get(fallbackName);
- if (fallback == null) {
- fallback = sSystemFallbackMap.get(DEFAULT_FAMILY);
- }
- long[] ptrArray = new long[families.length + fallback.length];
+ int weight, int italic) {
+ long[] ptrArray = new long[families.length + sFallbackFonts.length];
for (int i = 0; i < families.length; i++) {
ptrArray[i] = families[i].mNativePtr;
}
- for (int i = 0; i < fallback.length; i++) {
- ptrArray[i + families.length] = fallback[i].mNativePtr;
+ for (int i = 0; i < sFallbackFonts.length; i++) {
+ ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr;
}
return new Typeface(nativeCreateFromArray(ptrArray, weight, italic));
}
@@ -891,189 +885,113 @@
mWeight = nativeGetWeight(ni);
}
- private static @Nullable ByteBuffer mmap(String fullPath) {
- try (FileInputStream file = new FileInputStream(fullPath)) {
- final FileChannel fileChannel = file.getChannel();
- final long fontSize = fileChannel.size();
- return fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
- } catch (IOException e) {
- Log.e(TAG, "Error mapping font file " + fullPath);
- return null;
- }
- }
-
- private static @Nullable FontFamily createFontFamily(
- String familyName, List<FontConfig.Font> fonts, String languageTag, int variant,
- Map<String, ByteBuffer> cache, String fontDir) {
- final FontFamily family = new FontFamily(languageTag, variant);
- for (int i = 0; i < fonts.size(); i++) {
- final FontConfig.Font font = fonts.get(i);
- final String fullPath = fontDir + font.getFontName();
- ByteBuffer buffer = cache.get(fullPath);
- if (buffer == null) {
- if (cache.containsKey(fullPath)) {
- continue; // Already failed to mmap. Skip it.
- }
- buffer = mmap(fullPath);
- cache.put(fullPath, buffer);
- if (buffer == null) {
+ private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
+ Map<String, ByteBuffer> bufferForPath) {
+ FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
+ for (FontConfig.Font font : family.getFonts()) {
+ String fullPathName = "/system/fonts/" + font.getFontName();
+ ByteBuffer fontBuffer = bufferForPath.get(fullPathName);
+ if (fontBuffer == null) {
+ try (FileInputStream file = new FileInputStream(fullPathName)) {
+ FileChannel fileChannel = file.getChannel();
+ long fontSize = fileChannel.size();
+ fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
+ bufferForPath.put(fullPathName, fontBuffer);
+ } catch (IOException e) {
+ Log.e(TAG, "Error mapping font file " + fullPathName);
continue;
}
}
- if (!family.addFontFromBuffer(buffer, font.getTtcIndex(), font.getAxes(),
+ if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(),
font.getWeight(), font.isItalic() ? STYLE_ITALIC : STYLE_NORMAL)) {
- Log.e(TAG, "Error creating font " + fullPath + "#" + font.getTtcIndex());
+ Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex());
}
}
- if (!family.freeze()) {
- Log.e(TAG, "Unable to load Family: " + familyName + " : " + languageTag);
+ if (!fontFamily.freeze()) {
+ // Treat as system error since reaching here means that a system pre-installed font
+ // can't be used by our font stack.
+ Log.e(TAG, "Unable to load Family: " + family.getName() + ":" + family.getLanguage());
return null;
}
- return family;
+ return fontFamily;
}
- private static void pushFamilyToFallback(FontConfig.Family xmlFamily,
- ArrayMap<String, ArrayList<FontFamily>> fallbackMap,
- Map<String, ByteBuffer> cache,
- String fontDir) {
-
- final String languageTag = xmlFamily.getLanguage();
- final int variant = xmlFamily.getVariant();
-
- final ArrayList<FontConfig.Font> defaultFonts = new ArrayList<>();
- final ArrayMap<String, ArrayList<FontConfig.Font>> specificFallbackFonts = new ArrayMap<>();
-
- // Collect default fallback and specific fallback fonts.
- for (final FontConfig.Font font : xmlFamily.getFonts()) {
- final String fallbackName = font.getFallbackFor();
- if (fallbackName == null) {
- defaultFonts.add(font);
- } else {
- ArrayList<FontConfig.Font> fallback = specificFallbackFonts.get(fallbackName);
- if (fallback == null) {
- fallback = new ArrayList<>();
- specificFallbackFonts.put(fallbackName, fallback);
- }
- fallback.add(font);
- }
- }
-
- final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily(
- xmlFamily.getName(), defaultFonts, languageTag, variant, cache, fontDir);
-
- // Insert family into fallback map.
- for (int i = 0; i < fallbackMap.size(); i++) {
- final ArrayList<FontConfig.Font> fallback =
- specificFallbackFonts.get(fallbackMap.keyAt(i));
- if (fallback == null) {
- if (defaultFamily != null) {
- fallbackMap.valueAt(i).add(defaultFamily);
- }
- } else {
- final FontFamily family = createFontFamily(
- xmlFamily.getName(), fallback, languageTag, variant, cache, fontDir);
- if (family != null) {
- fallbackMap.valueAt(i).add(family);
- }
- }
- }
- }
-
- /**
- * Build the system fallback from xml file.
+ /*
+ * (non-Javadoc)
*
- * @param xmlPath A full path string to the fonts.xml file.
- * @param fontDir A full path string to the system font directory. This must end with
- * slash('/').
- * @param fontMap An output system font map. Caller must pass empty map.
- * @param fallbackMap An output system fallback map. Caller must pass empty map.
- * @hide
+ * This should only be called once, from the static class initializer block.
*/
- @VisibleForTesting
- public static void buildSystemFallback(String xmlPath, String fontDir,
- ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
+ private static void init() {
+ // Load font config and initialize Minikin state
+ File systemFontConfigLocation = getSystemFontConfigLocation();
+ File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
try {
- final FileInputStream fontsIn = new FileInputStream(xmlPath);
- final FontConfig fontConfig = FontListParser.parse(fontsIn);
+ FileInputStream fontsIn = new FileInputStream(configFilename);
+ FontConfig fontConfig = FontListParser.parse(fontsIn);
- final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>();
- final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies();
+ Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
- final ArrayMap<String, ArrayList<FontFamily>> fallbackListMap = new ArrayMap<>();
- // First traverse families which have a 'name' attribute to create fallback map.
- for (final FontConfig.Family xmlFamily : xmlFamilies) {
- final String familyName = xmlFamily.getName();
- if (familyName == null) {
- continue;
- }
- final FontFamily family = createFontFamily(
- xmlFamily.getName(), Arrays.asList(xmlFamily.getFonts()),
- xmlFamily.getLanguage(), xmlFamily.getVariant(), bufferCache, fontDir);
- if (family == null) {
- continue;
- }
- final ArrayList<FontFamily> fallback = new ArrayList<>();
- fallback.add(family);
- fallbackListMap.put(familyName, fallback);
- }
-
- // Then, add fallback fonts to the each fallback map.
- for (int i = 0; i < xmlFamilies.length; i++) {
- final FontConfig.Family xmlFamily = xmlFamilies[i];
- // The first family (usually the sans-serif family) is always placed immediately
- // after the primary family in the fallback.
- if (i == 0 || xmlFamily.getName() == null) {
- pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache, fontDir);
+ List<FontFamily> familyList = new ArrayList<FontFamily>();
+ // Note that the default typeface is always present in the fallback list;
+ // this is an enhancement from pre-Minikin behavior.
+ for (int i = 0; i < fontConfig.getFamilies().length; i++) {
+ FontConfig.Family f = fontConfig.getFamilies()[i];
+ if (i == 0 || f.getName() == null) {
+ FontFamily family = makeFamilyFromParsed(f, bufferForPath);
+ if (family != null) {
+ familyList.add(family);
+ }
}
}
+ sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
+ setDefault(Typeface.createFromFamilies(sFallbackFonts));
- // Build the font map and fallback map.
- for (int i = 0; i < fallbackListMap.size(); i++) {
- final String fallbackName = fallbackListMap.keyAt(i);
- final List<FontFamily> familyList = fallbackListMap.valueAt(i);
- final FontFamily[] families = familyList.toArray(new FontFamily[familyList.size()]);
-
- fallbackMap.put(fallbackName, families);
- final long[] ptrArray = new long[families.length];
- for (int j = 0; j < families.length; j++) {
- ptrArray[j] = families[j].mNativePtr;
+ Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
+ for (int i = 0; i < fontConfig.getFamilies().length; i++) {
+ Typeface typeface;
+ FontConfig.Family f = fontConfig.getFamilies()[i];
+ if (f.getName() != null) {
+ if (i == 0) {
+ // The first entry is the default typeface; no sense in
+ // duplicating the corresponding FontFamily.
+ typeface = sDefaultTypeface;
+ } else {
+ FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
+ if (fontFamily == null) {
+ continue;
+ }
+ FontFamily[] families = { fontFamily };
+ typeface = Typeface.createFromFamiliesWithDefault(families,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ }
+ systemFonts.put(f.getName(), typeface);
}
- fontMap.put(fallbackName, new Typeface(nativeCreateFromArray(
- ptrArray, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)));
}
-
- // Insert alias to font maps.
- for (final FontConfig.Alias alias : fontConfig.getAliases()) {
- Typeface base = fontMap.get(alias.getToName());
+ for (FontConfig.Alias alias : fontConfig.getAliases()) {
+ Typeface base = systemFonts.get(alias.getToName());
Typeface newFace = base;
int weight = alias.getWeight();
if (weight != 400) {
newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
}
- fontMap.put(alias.getName(), newFace);
+ systemFonts.put(alias.getName(), newFace);
}
+ sSystemFontMap = systemFonts;
+
} catch (RuntimeException e) {
Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e);
// TODO: normal in non-Minikin case, remove or make error when Minikin-only
} catch (FileNotFoundException e) {
- Log.e(TAG, "Error opening " + xmlPath, e);
+ Log.e(TAG, "Error opening " + configFilename, e);
} catch (IOException e) {
- Log.e(TAG, "Error reading " + xmlPath, e);
+ Log.e(TAG, "Error reading " + configFilename, e);
} catch (XmlPullParserException e) {
- Log.e(TAG, "XML parse exception for " + xmlPath, e);
+ Log.e(TAG, "XML parse exception for " + configFilename, e);
}
}
static {
- final ArrayMap<String, Typeface> systemFontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> systemFallbackMap = new ArrayMap<>();
- buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", systemFontMap,
- systemFallbackMap);
- sSystemFontMap = Collections.unmodifiableMap(systemFontMap);
- sSystemFallbackMap = Collections.unmodifiableMap(systemFallbackMap);
-
- setDefault(sSystemFontMap.get(DEFAULT_FAMILY));
-
+ init();
// Set up defaults and typefaces exposed in public API
DEFAULT = create((String) null, 0);
DEFAULT_BOLD = create((String) null, Typeface.BOLD);
@@ -1090,6 +1008,10 @@
}
+ private static File getSystemFontConfigLocation() {
+ return new File("/system/etc/");
+ }
+
@Override
protected void finalize() throws Throwable {
try {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 55eeb7f..61b3876 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -241,7 +241,8 @@
if (CC_LIKELY(layerType != LayerType::RenderLayer)
|| CC_UNLIKELY(!isRenderable())
|| CC_UNLIKELY(properties().getWidth() == 0)
- || CC_UNLIKELY(properties().getHeight() == 0)) {
+ || CC_UNLIKELY(properties().getHeight() == 0)
+ || CC_UNLIKELY(!properties().fitsOnLayer())) {
if (CC_UNLIKELY(hasLayer())) {
renderthread::CanvasContext::destroyLayer(this);
}
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index d96e376..f66bb04 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -68,7 +68,7 @@
Typeface* gDefaultTypeface = NULL;
Typeface* Typeface::resolveDefault(Typeface* src) {
- LOG_ALWAYS_FATAL_IF(src == nullptr && gDefaultTypeface == nullptr);
+ LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr);
return src == nullptr ? gDefaultTypeface : src;
}
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 6677178..59597af 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2101,9 +2101,7 @@
private int getMimeType(BufferedInputStream in) throws IOException {
in.mark(SIGNATURE_CHECK_SIZE);
byte[] signatureCheckBytes = new byte[SIGNATURE_CHECK_SIZE];
- if (in.read(signatureCheckBytes) != SIGNATURE_CHECK_SIZE) {
- throw new EOFException();
- }
+ in.read(signatureCheckBytes);
in.reset();
if (isJpegFormat(signatureCheckBytes)) {
return IMAGE_TYPE_JPEG;
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index e2642c9..bf18a7d 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -3044,6 +3044,8 @@
public static final int DolbyVisionProfileDvheStn = 0x20;
public static final int DolbyVisionProfileDvheDth = 0x40;
public static final int DolbyVisionProfileDvheDtb = 0x80;
+ public static final int DolbyVisionProfileDvheSt = 0x100;
+ public static final int DolbyVisionProfileDvavSe = 0x200;
// from OMX_VIDEO_DOLBYVISIONLEVELTYPE
public static final int DolbyVisionLevelHd24 = 0x1;
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 7dd70d4..4ea4e381 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -16,6 +16,7 @@
package android.media;
+import android.annotation.IntDef;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
@@ -27,6 +28,8 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Map;
@@ -246,16 +249,67 @@
* {@link #OPTION_CLOSEST} often has larger performance overhead compared
* to the other options if there is no sync frame located at timeUs.
*
- * @return A Bitmap containing a representative video frame, which
+ * @return A Bitmap containing a representative video frame, which
* can be null, if such a frame cannot be retrieved.
*/
- public Bitmap getFrameAtTime(long timeUs, int option) {
+ public Bitmap getFrameAtTime(long timeUs, @Option int option) {
if (option < OPTION_PREVIOUS_SYNC ||
option > OPTION_CLOSEST) {
throw new IllegalArgumentException("Unsupported option: " + option);
}
- return _getFrameAtTime(timeUs, option);
+ return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/);
+ }
+
+ /**
+ * Retrieve a video frame near a given timestamp scaled to a desired size.
+ * Call this method after setDataSource(). This method finds a representative
+ * frame close to the given time position by considering the given option
+ * if possible, and returns it as a bitmap with same aspect ratio as the source
+ * while scaling it so that it fits into the desired size of dst_width by dst_height.
+ * This is useful for generating a thumbnail for an input data source or just to
+ * obtain a scaled frame at the given time position.
+ *
+ * @param timeUs The time position in microseconds where the frame will be retrieved.
+ * When retrieving the frame at the given time position, there is no
+ * guarantee that the data source has a frame located at the position.
+ * When this happens, a frame nearby will be returned. If timeUs is
+ * negative, time position and option will ignored, and any frame
+ * that the implementation considers as representative may be returned.
+ *
+ * @param option a hint on how the frame is found. Use
+ * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
+ * that has a timestamp earlier than or the same as timeUs. Use
+ * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
+ * that has a timestamp later than or the same as timeUs. Use
+ * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
+ * that has a timestamp closest to or the same as timeUs. Use
+ * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
+ * or may not be a sync frame but is closest to or the same as timeUs.
+ * {@link #OPTION_CLOSEST} often has larger performance overhead compared
+ * to the other options if there is no sync frame located at timeUs.
+ *
+ * @param dstWidth expected output bitmap width
+ * @param dstHeight expected output bitmap height
+ * @return A Bitmap of size not larger than dstWidth by dstHeight containing a
+ * scaled video frame, which can be null, if such a frame cannot be retrieved.
+ * @throws IllegalArgumentException if passed in invalid option or width by height
+ * is less than or equal to 0.
+ */
+ public Bitmap getScaledFrameAtTime(
+ long timeUs, @Option int option, int dstWidth, int dstHeight) {
+ if (option < OPTION_PREVIOUS_SYNC ||
+ option > OPTION_CLOSEST) {
+ throw new IllegalArgumentException("Unsupported option: " + option);
+ }
+ if (dstWidth <= 0) {
+ throw new IllegalArgumentException("Invalid width: " + dstWidth);
+ }
+ if (dstHeight <= 0) {
+ throw new IllegalArgumentException("Invalid height: " + dstHeight);
+ }
+
+ return _getFrameAtTime(timeUs, option, dstWidth, dstHeight);
}
/**
@@ -273,8 +327,8 @@
* negative, time position and option will ignored, and any frame
* that the implementation considers as representative may be returned.
*
- * @return A Bitmap containing a representative video frame, which
- * can be null, if such a frame cannot be retrieved.
+ * @return A Bitmap of size dst_widthxdst_height containing a representative
+ * video frame, which can be null, if such a frame cannot be retrieved.
*
* @see #getFrameAtTime(long, int)
*/
@@ -297,17 +351,16 @@
* @see #getFrameAtTime(long, int)
*/
public Bitmap getFrameAtTime() {
- return getFrameAtTime(-1, OPTION_CLOSEST_SYNC);
+ return _getFrameAtTime(-1, OPTION_CLOSEST_SYNC, -1 /*dst_width*/, -1 /*dst_height*/);
}
- private native Bitmap _getFrameAtTime(long timeUs, int option);
+ private native Bitmap _getFrameAtTime(long timeUs, int option, int width, int height);
-
/**
* Call this method after setDataSource(). This method finds the optional
* graphic or album/cover art associated associated with the data source. If
* there are more than one pictures, (any) one of them is returned.
- *
+ *
* @return null if no such graphic is found.
*/
public byte[] getEmbeddedPicture() {
@@ -377,6 +430,16 @@
*/
public static final int OPTION_CLOSEST = 0x03;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "OPTION_" }, value = {
+ OPTION_PREVIOUS_SYNC,
+ OPTION_NEXT_SYNC,
+ OPTION_CLOSEST_SYNC,
+ OPTION_CLOSEST,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Option {}
+
/*
* Do not change these metadata key values without updating their
* counterparts in include/media/mediametadataretriever.h!
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 849bd01..5a16c36 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -73,6 +73,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
+import java.net.CookieHandler;
+import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
@@ -1004,19 +1006,28 @@
/**
* Sets the data source as a content Uri.
*
- * @param context the Context to use when resolving the Uri
- * @param uri the Content URI of the data you want to play
- * @param headers the headers to be sent together with the request for the data
- * The headers must not include cookies. Instead, use the cookies param.
- * @param cookies the cookies to be sent together with the request
- * @throws IllegalStateException if it is called in an invalid state
- * @throws NullPointerException if context or uri is null
- * @throws IOException if uri has a file scheme and an I/O error occurs
+ * To provide cookies for the subsequent HTTP requests, you can install your own default cookie
+ * handler and use other variants of setDataSource APIs instead. Alternatively, you can use
+ * this API to pass the cookies as a list of HttpCookie. If the app has not installed
+ * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with
+ * the provided cookies. If the app has installed its own handler already, this API requires the
+ * handler to be of CookieManager type such that the API can update the manager’s CookieStore.
*
* <p><strong>Note</strong> that the cross domain redirection is allowed by default,
* but that can be changed with key/value pairs through the headers parameter with
* "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
* disallow or allow cross domain redirection.
+ *
+ * @param context the Context to use when resolving the Uri
+ * @param uri the Content URI of the data you want to play
+ * @param headers the headers to be sent together with the request for the data
+ * The headers must not include cookies. Instead, use the cookies param.
+ * @param cookies the cookies to be sent together with the request
+ * @throws IllegalArgumentException if cookies are provided and the installed handler is not
+ * a CookieManager
+ * @throws IllegalStateException if it is called in an invalid state
+ * @throws NullPointerException if context or uri is null
+ * @throws IOException if uri has a file scheme and an I/O error occurs
*/
public void setDataSource(@NonNull Context context, @NonNull Uri uri,
@Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
@@ -1029,6 +1040,14 @@
throw new NullPointerException("uri param can not be null.");
}
+ if (cookies != null) {
+ CookieHandler cookieHandler = CookieHandler.getDefault();
+ if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) {
+ throw new IllegalArgumentException("The cookie handler has to be of CookieManager "
+ + "type when cookies are provided.");
+ }
+ }
+
// The context and URI usually belong to the calling user. Get a resolver for that user
// and strip out the userId from the URI if present.
final ContentResolver resolver = context.getContentResolver();
@@ -1064,15 +1083,15 @@
/**
* Sets the data source as a content Uri.
*
- * @param context the Context to use when resolving the Uri
- * @param uri the Content URI of the data you want to play
- * @param headers the headers to be sent together with the request for the data
- * @throws IllegalStateException if it is called in an invalid state
- *
* <p><strong>Note</strong> that the cross domain redirection is allowed by default,
* but that can be changed with key/value pairs through the headers parameter with
* "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
* disallow or allow cross domain redirection.
+ *
+ * @param context the Context to use when resolving the Uri
+ * @param uri the Content URI of the data you want to play
+ * @param headers the headers to be sent together with the request for the data
+ * @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(@NonNull Context context, @NonNull Uri uri,
@Nullable Map<String, String> headers)
@@ -1093,15 +1112,15 @@
/**
* Sets the data source (file-path or http/rtsp URL) to use.
*
- * @param path the path of the file, or the http/rtsp URL of the stream you want to play
- * @throws IllegalStateException if it is called in an invalid state
- *
* <p>When <code>path</code> refers to a local file, the file may actually be opened by a
* process other than the calling application. This implies that the pathname
* should be an absolute path (as any other process runs with unspecified current working
* directory), and that the pathname should reference a world-readable file.
* As an alternative, the application could first open the file for reading,
* and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
+ *
+ * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+ * @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(String path)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index ece19e4..c9b096f 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -256,7 +256,13 @@
*/
private void forceCloseConnection() {
if (mServiceConnection != null) {
- mContext.unbindService(mServiceConnection);
+ try {
+ mContext.unbindService(mServiceConnection);
+ } catch (IllegalArgumentException e) {
+ if (DBG) {
+ Log.d(TAG, "unbindService failed", e);
+ }
+ }
}
mState = CONNECT_STATE_DISCONNECTED;
mServiceConnection = null;
@@ -445,6 +451,9 @@
ResultReceiver receiver = new ResultReceiver(mHandler) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (!isConnected()) {
+ return;
+ }
if (resultCode != 0 || resultData == null
|| !resultData.containsKey(MediaBrowserService.KEY_MEDIA_ITEM)) {
cb.onError(mediaId);
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 07cfbda..df87e0f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -367,7 +367,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
if (mTvInputSessionImpl == null) {
// The session has been finished.
finishInputEvent(event, false);
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index b52906d..4df645d 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -700,6 +700,13 @@
new Result<MediaBrowser.MediaItem>(itemId) {
@Override
void onResultSent(MediaBrowser.MediaItem item, @ResultFlags int flag) {
+ if (mConnections.get(connection.callbacks.asBinder()) != connection) {
+ if (DBG) {
+ Log.d(TAG, "Not sending onLoadItem result for connection that has"
+ + " been disconnected. pkg=" + connection.pkg + " id=" + itemId);
+ }
+ return;
+ }
if ((flag & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) {
receiver.send(RESULT_ERROR, null);
return;
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 71f3856..4659ae1 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -244,9 +244,11 @@
}
}
-static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option)
+static jobject android_media_MediaMetadataRetriever_getFrameAtTime(
+ JNIEnv *env, jobject thiz, jlong timeUs, jint option, jint dst_width, jint dst_height)
{
- ALOGV("getFrameAtTime: %lld us option: %d", (long long)timeUs, option);
+ ALOGV("getFrameAtTime: %lld us option: %d dst width: %d heigh: %d",
+ (long long)timeUs, option, dst_width, dst_height);
MediaMetadataRetriever* retriever = getRetriever(env, thiz);
if (retriever == 0) {
jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
@@ -274,15 +276,19 @@
fields.createConfigMethod,
GraphicsJNI::colorTypeToLegacyBitmapConfig(kRGB_565_SkColorType));
- uint32_t width, height;
+ uint32_t width, height, displayWidth, displayHeight;
bool swapWidthAndHeight = false;
if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) {
width = videoFrame->mHeight;
height = videoFrame->mWidth;
swapWidthAndHeight = true;
+ displayWidth = videoFrame->mDisplayHeight;
+ displayHeight = videoFrame->mDisplayWidth;
} else {
width = videoFrame->mWidth;
height = videoFrame->mHeight;
+ displayWidth = videoFrame->mDisplayWidth;
+ displayHeight = videoFrame->mDisplayHeight;
}
jobject jBitmap = env->CallStaticObjectMethod(
@@ -308,22 +314,26 @@
videoFrame->mHeight,
videoFrame->mRotationAngle);
- if (videoFrame->mDisplayWidth != videoFrame->mWidth ||
- videoFrame->mDisplayHeight != videoFrame->mHeight) {
- uint32_t displayWidth = videoFrame->mDisplayWidth;
- uint32_t displayHeight = videoFrame->mDisplayHeight;
- if (swapWidthAndHeight) {
- displayWidth = videoFrame->mDisplayHeight;
- displayHeight = videoFrame->mDisplayWidth;
- }
+ if (dst_width <= 0 || dst_height <= 0) {
+ dst_width = displayWidth;
+ dst_height = displayHeight;
+ } else {
+ float factor = std::min((float)dst_width / (float)displayWidth,
+ (float)dst_height / (float)displayHeight);
+ dst_width = std::round(displayWidth * factor);
+ dst_height = std::round(displayHeight * factor);
+ }
+
+ if ((uint32_t)dst_width != videoFrame->mWidth ||
+ (uint32_t)dst_height != videoFrame->mHeight) {
ALOGV("Bitmap dimension is scaled from %dx%d to %dx%d",
- width, height, displayWidth, displayHeight);
+ width, height, dst_width, dst_height);
jobject scaledBitmap = env->CallStaticObjectMethod(fields.bitmapClazz,
- fields.createScaledBitmapMethod,
- jBitmap,
- displayWidth,
- displayHeight,
- true);
+ fields.createScaledBitmapMethod,
+ jBitmap,
+ dst_width,
+ dst_height,
+ true);
return scaledBitmap;
}
@@ -474,7 +484,7 @@
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
{"_setDataSource", "(Landroid/media/MediaDataSource;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceCallback},
- {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
+ {"_getFrameAtTime", "(JIII)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
{"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata},
{"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},
{"release", "()V", (void *)android_media_MediaMetadataRetriever_release},
diff --git a/packages/BackupRestoreConfirmation/res/values-en-rXC/strings.xml b/packages/BackupRestoreConfirmation/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..c42abe4
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-en-rXC/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="backup_confirm_title" msgid="827563724209303345">"Full backup"</string>
+ <string name="restore_confirm_title" msgid="5469365809567486602">"Full restore"</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"A full backup of all data to a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the backup yourself, do not allow the operation to proceed."</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"Back up my data"</string>
+ <string name="deny_backup_button_label" msgid="6009119115581097708">"Do not back up"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"A full restore of all data from a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the restore yourself, do not allow the operation to proceed. This will replace any data currently on the device!"</string>
+ <string name="allow_restore_button_label" msgid="3081286752277127827">"Restore my data"</string>
+ <string name="deny_restore_button_label" msgid="1724367334453104378">"Do not restore"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"Please enter your current backup password below:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Please enter your device encryption password below."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Please enter your device encryption password below. This will also be used to encrypt the backup archive."</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"If you wish to encrypt the full backup data, enter a password below:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Since your device is encrypted, you are required to encrypt your backup. Please enter a password below:"</string>
+ <string name="restore_enc_password_text" msgid="6140898525580710823">"If the restore data is encrypted, please enter the password below:"</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"Backup starting..."</string>
+ <string name="toast_backup_ended" msgid="3818080769548726424">"Backup finished"</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Restore starting..."</string>
+ <string name="toast_restore_ended" msgid="1764041639199696132">"Restore ended"</string>
+ <string name="toast_timeout" msgid="5276598587087626877">"Operation timed out"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml b/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..9a2051f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
+ <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
+ <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
+ <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
+ <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
+ <string name="ssl_error_warning" msgid="6653188881418638872">"The network you’re trying to join has security issues."</string>
+ <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page may not belong to the organization shown."</string>
+ <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
+</resources>
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index c309133..1cd7b61 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -34,6 +34,7 @@
<intent-filter>
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+ <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
@@ -43,10 +44,24 @@
android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
android:label="@string/action_bar_label"
android:theme="@style/AppTheme"
- android:configChanges="keyboardHidden|orientation|screenSize" >
+ android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+
+ <activity-alias
+ android:name="com.android.carrierdefaultapp.URLHandlerActivity"
+ android:targetActivity="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+ android:enabled="false" >
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ <data android:host="*" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..e30795d
--- /dev/null
+++ b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
+ <string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
+ <string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
+ <string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
+ <string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+ <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"No mobile data connection"</string>
+ <string name="no_mobile_data_connection" msgid="544980465184147010">"Add data or roaming plan through %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
+ <string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
+ <string name="ssl_error_warning" msgid="3127935140338254180">"The network you’re trying to join has security issues."</string>
+ <string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page may not belong to the organization shown."</string>
+ <string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
+</resources>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index a160186..c546fcee 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -3,7 +3,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mtoa Huduma za Simu"</string>
- <string name="portal_notification_id" msgid="5155057562457079297">"Data ya simu za mkononi imekwisha"</string>
+ <string name="portal_notification_id" msgid="5155057562457079297">"Data ya mtandao wa simu imekwisha"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Gonga ili utembelee tovuti ya %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Tafadhali wasiliana na mtoa huduma wako %s"</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 6194b87..b0052cc 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -20,6 +20,9 @@
import android.app.LoadedApk;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
@@ -34,6 +37,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
@@ -68,7 +72,7 @@
private static final boolean DBG = true;
private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
- public static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
+ private static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
private URL mUrl;
private Network mNetwork;
@@ -188,16 +192,19 @@
CarrierActionUtils.applyCarrierAction(
CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
getApplicationContext());
-
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER, getIntent(),
+ getApplicationContext());
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL, getIntent(),
+ getApplicationContext());
}
finishAndRemoveTask();
}
private URL getUrlForCaptivePortal() {
String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
- if (url.isEmpty()) {
- url = mCm.getCaptivePortalServerUrl();
- }
+ if (TextUtils.isEmpty(url)) url = mCm.getCaptivePortalServerUrl();
final CarrierConfigManager configManager = getApplicationContext()
.getSystemService(CarrierConfigManager.class);
final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
@@ -437,6 +444,27 @@
}
}
+ /**
+ * This alias presents the target activity, CaptivePortalLoginActivity, as a independent
+ * entity with its own intent filter to handle URL links. This alias will be enabled/disabled
+ * dynamically to handle url links based on the network conditions.
+ */
+ public static String getAlias(Context context) {
+ try {
+ PackageInfo p = context.getPackageManager().getPackageInfo(context.getPackageName(),
+ PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS);
+ for (ActivityInfo activityInfo : p.activities) {
+ String targetActivity = activityInfo.targetActivity;
+ if (CaptivePortalLoginActivity.class.getName().equals(targetActivity)) {
+ return activityInfo.name;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
private static void logd(String s) {
Rlog.d(TAG, s);
}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 0213306..a2bf964 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -19,8 +19,10 @@
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.telephony.SubscriptionManager;
@@ -49,6 +51,10 @@
public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION = 4;
public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS = 6;
+ public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER = 7;
+ public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER = 8;
+ public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL = 9;
+ public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL = 10;
public static void applyCarrierAction(int actionIdx, Intent intent, Context context) {
switch (actionIdx) {
@@ -73,6 +79,18 @@
case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS:
onCancelAllNotifications(context);
break;
+ case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER:
+ onEnableDefaultURLHandler(context);
+ break;
+ case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER:
+ onDisableDefaultURLHandler(context);
+ break;
+ case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL:
+ onRegisterDefaultNetworkAvail(intent, context);
+ break;
+ case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL:
+ onDeregisterDefaultNetworkAvail(intent, context);
+ break;
default:
loge("unsupported carrier action index: " + actionIdx);
}
@@ -94,6 +112,38 @@
telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
}
+ private static void onEnableDefaultURLHandler(Context context) {
+ logd("onEnableDefaultURLHandler");
+ final PackageManager pm = context.getPackageManager();
+ pm.setComponentEnabledSetting(
+ new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+ }
+
+ private static void onDisableDefaultURLHandler(Context context) {
+ logd("onDisableDefaultURLHandler");
+ final PackageManager pm = context.getPackageManager();
+ pm.setComponentEnabledSetting(
+ new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+ }
+
+ private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
+ int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultVoiceSubscriptionId());
+ logd("onRegisterDefaultNetworkAvail subId: " + subId);
+ final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+ telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
+ }
+
+ private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
+ int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultVoiceSubscriptionId());
+ logd("onDeregisterDefaultNetworkAvail subId: " + subId);
+ final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+ telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
+ }
+
private static void onDisableRadio(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
index d5d0b79..02c61d7 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
@@ -22,7 +22,6 @@
import android.telephony.Rlog;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;
@@ -95,6 +94,12 @@
configs = b.getStringArray(CarrierConfigManager
.KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET);
break;
+ case TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE:
+ configs = b.getStringArray(CarrierConfigManager
+ .KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE);
+ arg1 = String.valueOf(intent.getBooleanExtra(TelephonyIntents
+ .EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, false));
+ break;
default:
Rlog.e(TAG, "load carrier config failure with un-configured key: " +
intent.getAction());
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 30c1fff..7e23ee1 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -55,8 +55,6 @@
Log.e(LOG_TAG, "About to show UI, but no devices to show");
}
- mPairButton = findViewById(R.id.button_pair);
-
if (getService().mRequest.isSingleDevice()) {
setContentView(R.layout.device_confirmation);
final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
@@ -64,11 +62,13 @@
R.string.confirmation_title,
getCallingAppName(),
selectedDevice.getDisplayName()), 0));
+ mPairButton = findViewById(R.id.button_pair);
mPairButton.setOnClickListener(v -> onDeviceConfirmed(getService().mSelectedDevice));
getService().mSelectedDevice = selectedDevice;
onSelectionUpdate();
} else {
setContentView(R.layout.device_chooser);
+ mPairButton = findViewById(R.id.button_pair);
mPairButton.setVisibility(View.GONE);
setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
mDeviceListView = findViewById(R.id.device_list);
diff --git a/packages/DefaultContainerService/res/values-en-rXC/strings.xml b/packages/DefaultContainerService/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..d062fa8
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..e4f1b35
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
+ <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
+ <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
+ <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-en-rXC/strings.xml b/packages/FusedLocation/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..b085aba
--- /dev/null
+++ b/packages/FusedLocation/res/values-en-rXC/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-en-rXC/strings.xml b/packages/InputDevices/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..b9de6e7
--- /dev/null
+++ b/packages/InputDevices/res/values-en-rXC/strings.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+ <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android keyboard"</string>
+ <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+ <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+ <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), International style"</string>
+ <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), Colemak style"</string>
+ <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), Dvorak style"</string>
+ <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"English (US), Workman style"</string>
+ <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+ <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+ <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
+ <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russian"</string>
+ <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, Mac style"</string>
+ <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
+ <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Swiss French"</string>
+ <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Swiss German"</string>
+ <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgian"</string>
+ <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarian"</string>
+ <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+ <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+ <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+ <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+ <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
+ <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croatian"</string>
+ <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
+ <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonian"</string>
+ <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+ <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
+ <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilian"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
+ <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovak"</string>
+ <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
+ <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainian"</string>
+ <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabic"</string>
+ <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greek"</string>
+ <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrew"</string>
+ <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lithuanian"</string>
+ <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanish (Latin)"</string>
+ <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latvian"</string>
+</resources>
diff --git a/packages/MtpDocumentsProvider/res/values-en-rXC/strings.xml b/packages/MtpDocumentsProvider/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..370cca5
--- /dev/null
+++ b/packages/MtpDocumentsProvider/res/values-en-rXC/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="6271216747302322594">"MTP Host"</string>
+ <string name="downloads_app_label" msgid="7120690641874849726">"Downloads"</string>
+ <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
+ <string name="accessing_notification_title" msgid="3030133609230917944">"Accessing files from <xliff:g id="DEVICE_MODEL">%1$s</xliff:g>"</string>
+ <string name="error_busy_device" msgid="3997316850357386589">"The other device is busy. You can\'t transfer files until it\'s available."</string>
+ <string name="error_locked_device" msgid="7557872102188356147">"No files found. The other device may be locked. If so, unlock it and try again."</string>
+</resources>
diff --git a/packages/PrintSpooler/res/values-en-rXC/strings.xml b/packages/PrintSpooler/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..2063889
--- /dev/null
+++ b/packages/PrintSpooler/res/values-en-rXC/strings.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4469836075319831821">"Print Spooler"</string>
+ <string name="more_options_button" msgid="2243228396432556771">"More options"</string>
+ <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+ <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+ <string name="label_copies_summary" msgid="3861966063536529540">"Copies:"</string>
+ <string name="label_paper_size" msgid="908654383827777759">"Paper size"</string>
+ <string name="label_paper_size_summary" msgid="5668204981332138168">"Paper size:"</string>
+ <string name="label_color" msgid="1108690305218188969">"Color"</string>
+ <string name="label_duplex" msgid="5370037254347072243">"Two-sided"</string>
+ <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+ <string name="label_pages" msgid="7768589729282182230">"Pages"</string>
+ <string name="destination_default_text" msgid="5422708056807065710">"Select a printer"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"All <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Range of <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1—5,8,11—13"</string>
+ <string name="print_preview" msgid="8010217796057763343">"Print preview"</string>
+ <string name="install_for_print_preview" msgid="6366303997385509332">"Install PDF viewer for preview"</string>
+ <string name="printing_app_crashed" msgid="854477616686566398">"Printing app crashed"</string>
+ <string name="generating_print_job" msgid="3119608742651698916">"Generating print job"</string>
+ <string name="save_as_pdf" msgid="5718454119847596853">"Save as PDF"</string>
+ <string name="all_printers" msgid="5018829726861876202">"All printers…"</string>
+ <string name="print_dialog" msgid="32628687461331979">"Print dialog"</string>
+ <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Page <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> of <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Summary, copies <xliff:g id="COPIES">%1$s</xliff:g>, paper size <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Expand handle"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Collapse handle"</string>
+ <string name="print_button" msgid="645164566271246268">"Print"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Save to PDF"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Print options expanded"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Print options collapsed"</string>
+ <string name="search" msgid="5421724265322228497">"Search"</string>
+ <string name="all_printers_label" msgid="3178848870161526399">"All printers"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"Add service"</string>
+ <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Search box shown"</string>
+ <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Search box hidden"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"Add printer"</string>
+ <string name="print_select_printer" msgid="7388760939873368698">"Select printer"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"Forget printer"</string>
+ <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> printer found</item>
+ </plurals>
+ <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="printer_info_desc" msgid="7181988788991581654">"More information about this printer"</string>
+ <string name="notification_channel_progress" msgid="872788690775721436">"Running print jobs"</string>
+ <string name="notification_channel_failure" msgid="9042250774797916414">"Failed print jobs"</string>
+ <string name="could_not_create_file" msgid="3425025039427448443">"Could not create file"</string>
+ <string name="print_services_disabled_toast" msgid="9089060734685174685">"Some print services are disabled"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
+ <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string>
+ <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
+ <string name="cannot_add_printer" msgid="7840348733668023106">"Cannot add printers"</string>
+ <string name="select_to_add_printers" msgid="3800709038689830974">"Select to add printer"</string>
+ <string name="enable_print_service" msgid="3482815747043533842">"Select to enable"</string>
+ <string name="enabled_services_title" msgid="7036986099096582296">"Enabled services"</string>
+ <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string>
+ <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string>
+ <string name="all_services_title" msgid="5578662754874906455">"All services"</string>
+ <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
+ <item quantity="other">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+ <item quantity="one">Install to discover <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item>
+ </plurals>
+ <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer blocked <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="cancel" msgid="4373674107267141885">"Cancel"</string>
+ <string name="restart" msgid="2472034227037808749">"Restart"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
+ <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
+ <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+ <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
+ <string-array name="color_mode_labels">
+ <item msgid="7602948745415174937">"Black & White"</item>
+ <item msgid="2762241247228983754">"Color"</item>
+ </string-array>
+ <string-array name="duplex_mode_labels">
+ <item msgid="3882302912790928315">"None"</item>
+ <item msgid="7296563835355641719">"Long edge"</item>
+ <item msgid="79513688117503758">"Short edge"</item>
+ </string-array>
+ <string-array name="orientation_labels">
+ <item msgid="4061931020926489228">"Portrait"</item>
+ <item msgid="3199660090246166812">"Landscape"</item>
+ </string-array>
+ <string name="print_write_error_message" msgid="5787642615179572543">"Couldn\'t write to file"</string>
+ <string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
+ <string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+ <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
+ <string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
+</resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 2cb292e..866aa0f 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Gekoppel, geen internet nie"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt is tydelik vol"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Gekoppel via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Beskikbaar via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Baie stadig"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Stadig"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi twee stawe."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi drie stawe."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-sein vol."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Oop netwerk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Veilige netwerk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android-bedryfstelsel"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Verwyderde programme"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Verwyderde programme en gebruikers"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laai tans"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Laai nie"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Beheer deur administrateur"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Geaktiveer deur administrateur"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 8d220e2..100a5b2 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"ተገናኝቷል፣ ምንም በይነመረብ የለም"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"የመዳረሻ ነጥብ ለጊዜው ሞልቷል"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"በ%1$s በኩል ተገናኝቷል"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"በ%1$s በኩል የሚገኝ"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"በጣም ቀርፋፋ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"አዘግይ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"እሺ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ሁለት የWiFi አሞሌዎች።"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ሦስት የWiFi አሞሌዎች።"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"የWiFi ምልክት ሙሉ ነው።"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"አውታረ መረብ ክፈት"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ደህንነቱ የተጠበቀ አውታረ መረብ"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android ስርዓተ ክወና"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"የተወገዱ መተግበሪያዎች"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"የተወገዱ መተግበሪያዎች እና ተጠቃሚዎች"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ባትሪ እየሞላ አይደለም"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል እየሞላ አይደለም"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"በአስተዳዳሪ ነቅቷል"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index f076d56..67d0a91 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"تم الاتصال عبر %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"متوفرة عبر %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصلة، ولا يتوفر إنترنت"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"نقطة الدخول ممتلئة مؤقتًا"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"تم الاتصال عبر %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"متوفرة عبر %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"بطيئة جدًا"</string>
<string name="speed_label_slow" msgid="813109590815810235">"بطيئة"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"موافق"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"إشارة Wi-Fi تتكون من شريطين."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"إشارة Wi-Fi تتكون من ثلاثة أشرطة."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"إشارة Wi-Fi كاملة."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"شبكة مفتوحة"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"شبكة محمية بكلمة مرور"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"نظام التشغيل Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"التطبيقات المزالة"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"التطبيقات والمستخدمون الذين تمت إزالتهم"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"جارٍ الشحن"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"لا يتم الشحن"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"إعدادات يتحكم فيها المشرف"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"تم تمكين الإعداد بواسطة المشرف"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 8c5206b..1732c87 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Qoşuludur, internet yoxdur"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Giriş nöqtəsi müvəqqəti olaraq doludur"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ilə qoşuludur"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s vasitəsilə əlçatandır"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Çox Yavaş"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi iki xətdir."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi üç xətdir."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi siqnalı tamdır."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Açıq şəbəkə"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Təhlükəsiz şəbəkə"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Silinmiş tətbiqlər"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Tətbiqləri və istifadəçiləri silin"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"enerji yığır"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Doldurulmur"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Admin tərəfindən nəzarət olunur"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Admin tərəfindən aktiv edildi"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index b2cf781..3336164 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Veza je uspostavljena, nema interneta"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno zauzeta"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Povezano preko %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dostupno preko %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veoma spora"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Spora"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Potvrdi"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi signal ima dve crte."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi signal ima tri crte."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal je najjači."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Otvorena mreža"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Bezbedna mreža"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"puni se"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio je administrator"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index e7030b3..b50285f 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Падлучана, няма інтэрнэту"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пункт доступу часова заняты"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Падлучана праз %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Даступна праз %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Вельмі павольная"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Павольная"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Два слупкi Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Тры слупкi Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Поўны сігнал Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Адкрытая сетка"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Бяспечная сетка"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"АС Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Выдаленыя прыкладанні"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Выдаленыя прыкладанні і карыстальнiкi"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ідзе зарадка"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не зараджаецца"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Кантралюецца адміністратарам"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Уключана адміністратарам"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 33f8017..ef3f1f6 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Установена е връзка – няма достъп до интернет"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точката за достъп временно е пълна"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Установена е връзка през %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Мрежата е достъпна през %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Много бавна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi е с две чертички."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi е с три чертички."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Сигналът за Wi-Fi е пълен."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Отворена мрежа"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Защитена мрежа"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android (ОС)"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Премахнати приложения"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Премахнати приложения и потребители"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарежда се"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не се зарежда"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролира се от администратор"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Активирано от администратора"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1fcb669..2cf2730 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"সংযুক্ত, ইন্টারনেট নেই"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"এই মুহূর্তে অ্যাক্সেস পয়েন্টের কোনও কানেকশন ফাঁকা নেই"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s এর মাধ্যমে সংযুক্ত হয়েছে"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s এর মাধ্যমে পাওয়া যাচ্ছে"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"খুব ধীরে"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ধীরে"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ঠিক আছে"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ওয়াই ফাই এ দুইটি দণ্ড৷"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ওয়াই ফাই এ তিনটি দণ্ড৷"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ওয়াই ফাই এ সম্পূর্ণ সিগন্যাল৷"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"খোলা নেটওয়ার্ক"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"সুরক্ষিত নেটওয়ার্ক"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"সরানো অ্যাপ্লিকেশানগুলি"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"সরানো অ্যাপ্লিকেশানগুলি এবং ব্যবহারকারীগণ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চার্জ হচ্ছে"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"চার্জ হচ্ছে না"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"প্রশাসক দ্বারা সক্ষম করা হয়েছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index d52f144..614bdb1 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano. Nema interneta"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno puna"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Povezana koristeći %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dostupna koristeći %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veoma sporo"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sporo"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"UREDU"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dvije crtice."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tri crtice."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi puni signal."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Otvorena mreža"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sigurna mreža"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pod kontrolom administratora"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8691bd8..b2b2b1c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connectada, sense Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punt d\'accés està temporalment ple"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connectat mitjançant %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponible mitjançant %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Molt lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Correcta"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Senyal Wi-Fi: dues barres."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Senyal Wi-Fi: tres barres."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Senyal Wi-Fi: complet."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Xarxa oberta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Xarxa segura"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicacions eliminades"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicacions i usuaris eliminats"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"s\'està carregant"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"No s\'està carregant"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Activada per l\'administrador"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index f4c40c7..fcb0b02 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Připojeno, není k dispozici internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Přístupový bod je dočasně zaplněn"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Připojeno prostřednictvím %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dostupné prostřednictvím %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Velmi pomalá"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Pomalá"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi – dvě čárky."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi – tři čárky."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi – plný signál."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Nezabezpečená síť"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Zabezpečená síť"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Odebrané aplikace"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Odebrané aplikace a odebraní uživatelé"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíjení"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíjí se"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Spravováno administrátorem"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Zapnuto administrátorem"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index f5a4191..1c40c52 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilsluttet – intet internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Adgangspunktet er midlertidigt fuldt"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Tilsluttet via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Tilgængelig via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Meget langsom"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langsom"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi har to bjælker."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi har tre bjælker."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi har fuldt signal."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Åbent netværk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sikkert netværk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Fjernede apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Fjernede apps og brugere"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"oplader"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Oplader ikke"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolleret af administratoren"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Aktiveret af administratoren"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 4e01574..8c0e727 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbunden, kein Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Zugangspunkt vorübergehend voll belegt"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Über %1$s verbunden"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Verfügbar über %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sehr langsam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langsam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WLAN: zwei Balken"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WLAN: drei Balken"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WLAN: volle Signalstärke"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Offenes Netzwerk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sicheres Netzwerk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Entfernte Apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Entfernte Apps und Nutzer"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"wird aufgeladen..."</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Wird nicht geladen"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Durch den Administrator verwaltet"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Vom Administrator aktiviert"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 22d2558..46aa2c5 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Συνδέθηκε, χωρίς διαδίκτυο"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Το σημείο πρόσβασης είναι προσωρινά πλήρες"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Συνδέθηκε μέσω %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Διαθέσιμο μέσω %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Πολύ αργή"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Αργή"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ΟΚ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Δύο γραμμές Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Τρεις γραμμές Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Άριστο σήμα Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Ανοικτό δίκτυο"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Ασφαλές δίκτυο"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Λειτουργικό σύστημα Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Εφαρμογές που καταργήθηκαν"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Εφαρμογές και χρήστες που έχουν καταργηθεί"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"φόρτιση"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Δεν φορτίζει"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ελέγχονται από το διαχειριστή"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Ενεργοποιήθηκε από τον διαχειριστή"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 11ef680..bbc1144 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 11ef680..bbc1144 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 11ef680..bbc1144 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
new file mode 100644
index 0000000..1a110ea
--- /dev/null
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations 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="wifi_status">
+ <item msgid="1922181315419294640"></item>
+ <item msgid="8934131797783724664">"Scanning…"</item>
+ <item msgid="8513729475867537913">"Connecting…"</item>
+ <item msgid="515055375277271756">"Authenticating…"</item>
+ <item msgid="1943354004029184381">"Obtaining IP address…"</item>
+ <item msgid="4221763391123233270">"Connected"</item>
+ <item msgid="624838831631122137">"Suspended"</item>
+ <item msgid="7979680559596111948">"Disconnecting…"</item>
+ <item msgid="1634960474403853625">"Disconnected"</item>
+ <item msgid="746097431216080650">"Unsuccessful"</item>
+ <item msgid="6367044185730295334">"Blocked"</item>
+ <item msgid="503942654197908005">"Temporarily avoiding poor connection"</item>
+ </string-array>
+ <string-array name="wifi_status_with_ssid">
+ <item msgid="7714855332363650812"></item>
+ <item msgid="8878186979715711006">"Scanning…"</item>
+ <item msgid="355508996603873860">"Connecting to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="554971459996405634">"Authenticating with <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="7928343808033020343">"Obtaining IP address from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="8937994881315223448">"Connected to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1330262655415760617">"Suspended"</item>
+ <item msgid="7698638434317271902">"Disconnecting from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="197508606402264311">"Disconnected"</item>
+ <item msgid="8578370891960825148">"Unsuccessful"</item>
+ <item msgid="5660739516542454527">"Blocked"</item>
+ <item msgid="1805837518286731242">"Temporarily avoiding poor connection"</item>
+ </string-array>
+ <string-array name="hdcp_checking_titles">
+ <item msgid="441827799230089869">"Never check"</item>
+ <item msgid="6042769699089883931">"Check for DRM content only"</item>
+ <item msgid="9174900380056846820">"Always check"</item>
+ </string-array>
+ <string-array name="hdcp_checking_summaries">
+ <item msgid="505558545611516707">"Never use HDCP checking"</item>
+ <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
+ <item msgid="45075631231212732">"Always use HDCP checking"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_versions">
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+ <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+ </string-array>
+ <string-array name="bluetooth_avrcp_version_values">
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="1913619118958233129">"avrcp15"</item>
+ <item msgid="7142710449249088270">"avrcp16"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_titles">
+ <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
+ <item msgid="7539690996561263909">"SBC"</item>
+ <item msgid="686685526567131661">"AAC"</item>
+ <item msgid="8910200421843557332">"aptX"</item>
+ <item msgid="8434403964359457768">"aptX HD"</item>
+ <item msgid="6751080638867012696">"LDAC"</item>
+ <item msgid="723675059572222462">"Enable Optional Codecs"</item>
+ <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_summaries">
+ <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
+ <item msgid="6898329690939802290">"SBC"</item>
+ <item msgid="6839647709301342559">"AAC"</item>
+ <item msgid="2279916056363477395">"aptX"</item>
+ <item msgid="6641171061200063516">"aptX HD"</item>
+ <item msgid="7950781694447359344">"LDAC"</item>
+ <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
+ <item msgid="741805482892725657">"Disable Optional Codecs"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+ <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
+ <item msgid="8895532488906185219">"44.1 kHz"</item>
+ <item msgid="2909915718994807056">"48.0 kHz"</item>
+ <item msgid="3347287377354164611">"88.2 kHz"</item>
+ <item msgid="1234212100239985373">"96.0 kHz"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
+ <item msgid="3214516120190965356">"Use System Selection (Default)"</item>
+ <item msgid="4482862757811638365">"44.1 kHz"</item>
+ <item msgid="354495328188724404">"48.0 kHz"</item>
+ <item msgid="7329816882213695083">"88.2 kHz"</item>
+ <item msgid="6967397666254430476">"96.0 kHz"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+ <item msgid="2684127272582591429">"Use System Selection (Default)"</item>
+ <item msgid="5618929009984956469">"16 bits/sample"</item>
+ <item msgid="3412640499234627248">"24 bits/sample"</item>
+ <item msgid="121583001492929387">"32 bits/sample"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
+ <item msgid="1081159789834584363">"Use System Selection (Default)"</item>
+ <item msgid="4726688794884191540">"16 bits/sample"</item>
+ <item msgid="305344756485516870">"24 bits/sample"</item>
+ <item msgid="244568657919675099">"32 bits/sample"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+ <item msgid="5226878858503393706">"Use System Selection (Default)"</item>
+ <item msgid="4106832974775067314">"Mono"</item>
+ <item msgid="5571632958424639155">"Stereo"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
+ <item msgid="4118561796005528173">"Use System Selection (Default)"</item>
+ <item msgid="8900559293912978337">"Mono"</item>
+ <item msgid="8883739882299884241">"Stereo"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+ <item msgid="7158319962230727476">"Optimized for Audio Quality (990kbps/909kbps)"</item>
+ <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660kbps/606kbps)"</item>
+ <item msgid="8860982705384396512">"Optimized for Connection Quality (330kbps/303kbps)"</item>
+ <item msgid="4414060457677684127">"Best Effort (Adaptive Bit Rate)"</item>
+ </string-array>
+ <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
+ <item msgid="6398189564246596868">"Optimized for Audio Quality"</item>
+ <item msgid="4327143584633311908">"Balanced Audio And Connection Quality"</item>
+ <item msgid="4681409244565426925">"Optimized for Connection Quality"</item>
+ <item msgid="364670732877872677">"Best Effort (Adaptive Bit Rate)"</item>
+ </string-array>
+ <string-array name="select_logd_size_titles">
+ <item msgid="8665206199209698501">"Off"</item>
+ <item msgid="1593289376502312923">"64K"</item>
+ <item msgid="487545340236145324">"256K"</item>
+ <item msgid="2423528675294333831">"1M"</item>
+ <item msgid="180883774509476541">"4M"</item>
+ <item msgid="2803199102589126938">"16M"</item>
+ </string-array>
+ <string-array name="select_logd_size_lowram_titles">
+ <item msgid="6089470720451068364">"Off"</item>
+ <item msgid="4622460333038586791">"64K"</item>
+ <item msgid="2212125625169582330">"256K"</item>
+ <item msgid="1704946766699242653">"1M"</item>
+ </string-array>
+ <string-array name="select_logd_size_summaries">
+ <item msgid="6921048829791179331">"Off"</item>
+ <item msgid="2969458029344750262">"64K per log buffer"</item>
+ <item msgid="1342285115665698168">"256K per log buffer"</item>
+ <item msgid="1314234299552254621">"1M per log buffer"</item>
+ <item msgid="3606047780792894151">"4M per log buffer"</item>
+ <item msgid="5431354956856655120">"16M per log buffer"</item>
+ </string-array>
+ <string-array name="select_logpersist_titles">
+ <item msgid="1744840221860799971">"Off"</item>
+ <item msgid="3054662377365844197">"All"</item>
+ <item msgid="688870735111627832">"All but radio"</item>
+ <item msgid="2850427388488887328">"kernel only"</item>
+ </string-array>
+ <string-array name="select_logpersist_summaries">
+ <item msgid="2216470072500521830">"Off"</item>
+ <item msgid="172978079776521897">"All log buffers"</item>
+ <item msgid="3873873912383879240">"All but radio log buffers"</item>
+ <item msgid="8489661142527693381">"kernel log buffer only"</item>
+ </string-array>
+ <string-array name="window_animation_scale_entries">
+ <item msgid="8134156599370824081">"Animation off"</item>
+ <item msgid="6624864048416710414">"Animation scale .5x"</item>
+ <item msgid="2219332261255416635">"Animation scale 1x"</item>
+ <item msgid="3544428804137048509">"Animation scale 1.5x"</item>
+ <item msgid="3110710404225974514">"Animation scale 2x"</item>
+ <item msgid="4402738611528318731">"Animation scale 5x"</item>
+ <item msgid="6189539267968330656">"Animation scale 10x"</item>
+ </string-array>
+ <string-array name="transition_animation_scale_entries">
+ <item msgid="8464255836173039442">"Animation off"</item>
+ <item msgid="3375781541913316411">"Animation scale .5x"</item>
+ <item msgid="1991041427801869945">"Animation scale 1x"</item>
+ <item msgid="4012689927622382874">"Animation scale 1.5x"</item>
+ <item msgid="3289156759925947169">"Animation scale 2x"</item>
+ <item msgid="7705857441213621835">"Animation scale 5x"</item>
+ <item msgid="6660750935954853365">"Animation scale 10x"</item>
+ </string-array>
+ <string-array name="animator_duration_scale_entries">
+ <item msgid="6039901060648228241">"Animation off"</item>
+ <item msgid="1138649021950863198">"Animation scale .5x"</item>
+ <item msgid="4394388961370833040">"Animation scale 1x"</item>
+ <item msgid="8125427921655194973">"Animation scale 1.5x"</item>
+ <item msgid="3334024790739189573">"Animation scale 2x"</item>
+ <item msgid="3170120558236848008">"Animation scale 5x"</item>
+ <item msgid="1069584980746680398">"Animation scale 10x"</item>
+ </string-array>
+ <string-array name="overlay_display_devices_entries">
+ <item msgid="1606809880904982133">"None"</item>
+ <item msgid="9033194758688161545">"480p"</item>
+ <item msgid="1025306206556583600">"480p (secure)"</item>
+ <item msgid="1853913333042744661">"720p"</item>
+ <item msgid="3414540279805870511">"720p (secure)"</item>
+ <item msgid="9039818062847141551">"1080p"</item>
+ <item msgid="4939496949750174834">"1080p (secure)"</item>
+ <item msgid="1833612718524903568">"4K"</item>
+ <item msgid="238303513127879234">"4K (secure)"</item>
+ <item msgid="3547211260846843098">"4K (upscaled)"</item>
+ <item msgid="5411365648951414254">"4K (upscaled, secure)"</item>
+ <item msgid="1311305077526792901">"720p, 1080p (dual screen)"</item>
+ </string-array>
+ <string-array name="enable_opengl_traces_entries">
+ <item msgid="3191973083884253830">"None"</item>
+ <item msgid="9089630089455370183">"Logcat"</item>
+ <item msgid="5397807424362304288">"Systrace (Graphics)"</item>
+ <item msgid="1340692776955662664">"Call stack on glGetError"</item>
+ </string-array>
+ <string-array name="show_non_rect_clip_entries">
+ <item msgid="993742912147090253">"Off"</item>
+ <item msgid="675719912558941285">"Draw non-rectangular clip region in blue"</item>
+ <item msgid="1064373276095698656">"Highlight tested drawing commands in green"</item>
+ </string-array>
+ <string-array name="track_frame_time_entries">
+ <item msgid="2193584639058893150">"Off"</item>
+ <item msgid="2751513398307949636">"On screen as bars"</item>
+ <item msgid="2355151170975410323">"In <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+ </string-array>
+ <string-array name="debug_hw_overdraw_entries">
+ <item msgid="8190572633763871652">"Off"</item>
+ <item msgid="7688197031296835369">"Show overdraw areas"</item>
+ <item msgid="2290859360633824369">"Show areas for Deuteranomaly"</item>
+ </string-array>
+ <string-array name="debug_hw_renderer_entries">
+ <item msgid="2578620445459945681">"OpenGL (Default)"</item>
+ <item msgid="2839130076198120436">"OpenGL (Skia)"</item>
+ </string-array>
+ <string-array name="app_process_limit_entries">
+ <item msgid="3401625457385943795">"Standard limit"</item>
+ <item msgid="4071574792028999443">"No background processes"</item>
+ <item msgid="4810006996171705398">"At most 1 process"</item>
+ <item msgid="8586370216857360863">"At most 2 processes"</item>
+ <item msgid="836593137872605381">"At most 3 processes"</item>
+ <item msgid="7899496259191969307">"At most 4 processes"</item>
+ </string-array>
+ <string-array name="usb_configuration_titles">
+ <item msgid="488237561639712799">"Charging"</item>
+ <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+ <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+ <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+ <item msgid="1718924214939774352">"Audio Source"</item>
+ <item msgid="8126315616613006284">"MIDI"</item>
+ </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..6af9692
--- /dev/null
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
+ <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
+ <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
+ <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
+ <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
+ <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi Connection Failure"</string>
+ <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
+ <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
+ <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+ <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
+ <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
+ <string name="wifi_no_internet" msgid="3880396223819116454">"No Internet access"</string>
+ <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
+ <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
+ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
+ <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
+ <string name="speed_label_very_slow" msgid="1867055264243608530">"Very Slow"</string>
+ <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
+ <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+ <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
+ <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
+ <string name="speed_label_very_fast" msgid="2265363430784523409">"Very Fast"</string>
+ <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
+ <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
+ <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
+ <string name="bluetooth_connected" msgid="6038755206916626419">"Connected"</string>
+ <string name="bluetooth_pairing" msgid="1426882272690346242">"Pairing…"</string>
+ <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Connected (no phone)"</string>
+ <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Connected (no media)"</string>
+ <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Connected (no message access)"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Connected (no phone or media)"</string>
+ <string name="bluetooth_connected_battery_level" msgid="7049181126136692368">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_battery_level" msgid="5504193961248406027">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="4751724026365870779">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1549265779323455261">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
+ <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
+ <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
+ <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
+ <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
+ <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
+ <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text Messages"</string>
+ <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
+ <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+ <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
+ <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file transfer server"</string>
+ <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Connected to map"</string>
+ <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Connected to SAP"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Not connected to file transfer server"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Connected to input device"</string>
+ <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"Connected to device for Internet access"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Sharing local Internet connection with device"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Use for Internet access"</string>
+ <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Use for map"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use for SIM access"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Use for media audio"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Use for phone audio"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Use for file transfer"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Use for input"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Pair"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PAIR"</string>
+ <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancel"</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Pairing grants access to your contacts and call history when connected."</string>
+ <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
+ <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi off."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi disconnected."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi signal full."</string>
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
+ <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+ <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
+ <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB tethering"</string>
+ <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Portable hotspot"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth tethering"</string>
+ <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Tethering"</string>
+ <string name="tether_settings_title_all" msgid="8356136101061143841">"Tethering & portable hotspot"</string>
+ <string name="managed_user_title" msgid="8109605045406748842">"All work apps"</string>
+ <string name="user_guest" msgid="8475274842845401871">"Guest"</string>
+ <string name="unknown" msgid="1592123443519355854">"Unknown"</string>
+ <string name="running_process_item_user_label" msgid="3129887865552025943">"User: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+ <string name="launch_defaults_some" msgid="313159469856372621">"Some defaults set"</string>
+ <string name="launch_defaults_none" msgid="4241129108140034876">"No defaults set"</string>
+ <string name="tts_settings" msgid="8186971894801348327">"Text-to-speech settings"</string>
+ <string name="tts_settings_title" msgid="1237820681016639683">"Text-to-speech output"</string>
+ <string name="tts_default_rate_title" msgid="6030550998379310088">"Speech rate"</string>
+ <string name="tts_default_rate_summary" msgid="4061815292287182801">"Speed at which the text is spoken"</string>
+ <string name="tts_default_pitch_title" msgid="6135942113172488671">"Pitch"</string>
+ <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Affects the tone of the synthesized speech"</string>
+ <string name="tts_default_lang_title" msgid="8018087612299820556">"Language"</string>
+ <string name="tts_lang_use_system" msgid="2679252467416513208">"Use system language"</string>
+ <string name="tts_lang_not_selected" msgid="7395787019276734765">"Language not selected"</string>
+ <string name="tts_default_lang_summary" msgid="5219362163902707785">"Sets the language-specific voice for the spoken text"</string>
+ <string name="tts_play_example_title" msgid="7094780383253097230">"Listen to an example"</string>
+ <string name="tts_play_example_summary" msgid="8029071615047894486">"Play a short demonstration of speech synthesis"</string>
+ <string name="tts_install_data_title" msgid="4264378440508149986">"Install voice data"</string>
+ <string name="tts_install_data_summary" msgid="5742135732511822589">"Install the voice data required for speech synthesis"</string>
+ <string name="tts_engine_security_warning" msgid="8786238102020223650">"This speech synthesis engine may be able to collect all the text that will be spoken, including personal data like passwords and credit card numbers. It comes from the <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> engine. Enable the use of this speech synthesis engine?"</string>
+ <string name="tts_engine_network_required" msgid="1190837151485314743">"This language requires a working network connection for text-to-speech output."</string>
+ <string name="tts_default_sample_string" msgid="4040835213373086322">"This is an example of speech synthesis"</string>
+ <string name="tts_status_title" msgid="7268566550242584413">"Default language status"</string>
+ <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
+ <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
+ <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
+ <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
+ <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
+ <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
+ <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
+ <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Reset speech pitch"</string>
+ <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Reset the pitch at which the text is spoken to default."</string>
+ <string-array name="tts_rate_entries">
+ <item msgid="6695494874362656215">"Very slow"</item>
+ <item msgid="4795095314303559268">"Slow"</item>
+ <item msgid="8903157781070679765">"Normal"</item>
+ <item msgid="164347302621392996">"Fast"</item>
+ <item msgid="5794028588101562009">"Faster"</item>
+ <item msgid="7163942783888652942">"Very fast"</item>
+ <item msgid="7831712693748700507">"Rapid"</item>
+ <item msgid="5194774745031751806">"Very rapid"</item>
+ <item msgid="9085102246155045744">"Fastest"</item>
+ </string-array>
+ <string name="choose_profile" msgid="6921016979430278661">"Choose profile"</string>
+ <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+ <string name="category_work" msgid="8699184680584175622">"Work"</string>
+ <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
+ <string name="development_settings_enable" msgid="542530994778109538">"Enable developer options"</string>
+ <string name="development_settings_summary" msgid="1815795401632854041">"Set options for app development"</string>
+ <string name="development_settings_not_available" msgid="4308569041701535607">"Developer options are not available for this user"</string>
+ <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN settings are not available for this user"</string>
+ <string name="tethering_settings_not_available" msgid="6765770438438291012">"Tethering settings are not available for this user"</string>
+ <string name="apn_settings_not_available" msgid="7873729032165324000">"Access Point Name settings are not available for this user"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"USB debugging"</string>
+ <string name="enable_adb_summary" msgid="4881186971746056635">"Debug mode when USB is connected"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Revoke USB debugging authorizations"</string>
+ <string name="bugreport_in_power" msgid="7923901846375587241">"Bug report shortcut"</string>
+ <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Show a button in the power menu for taking a bug report"</string>
+ <string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
+ <string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
+ <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
+ <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"Capture all bluetooth HCI packets in a file"</string>
+ <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
+ <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
+ <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
+ <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"WARNING: Device protection features will not work on this device while this setting is turned on."</string>
+ <string name="mock_location_app" msgid="7966220972812881854">"Select mock location app"</string>
+ <string name="mock_location_app_not_set" msgid="809543285495344223">"No mock location app set"</string>
+ <string name="mock_location_app_set" msgid="8966420655295102685">"Mock location app: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
+ <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
+ <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi Verbose Logging"</string>
+ <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Aggressive Wi‑Fi to mobile handover"</string>
+ <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+ <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
+ <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
+ <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Enable in-band ringing"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
+ <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Select Bluetooth Audio Codec"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"Select Bluetooth Audio Codec:\nSample Rate"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"Bluetooth Audio Bits Per Sample"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"Select Bluetooth Audio Codec:\nBits Per Sample"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"Bluetooth Audio Channel Mode"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"Select Bluetooth Audio Codec:\nChannel Mode"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string>
+ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
+ <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+ <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string>
+ <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Allow/Disallow Wi‑Fi Roam Scans based on the amount of data traffic present at the interface"</string>
+ <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
+ <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
+ <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Clear logger persistent storage?"</string>
+ <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"When we no longer are monitoring with the persistent logger, we are required to erase the logger data resident on your device."</string>
+ <string name="select_logpersist_title" msgid="7530031344550073166">"Store logger data persistently on device"</string>
+ <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Select log buffers to store persistently on device"</string>
+ <string name="select_usb_configuration_title" msgid="2649938511506971843">"Select USB Configuration"</string>
+ <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Select USB Configuration"</string>
+ <string name="allow_mock_location" msgid="2787962564578664888">"Allow mock locations"</string>
+ <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
+ <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+ <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification, and read log data."</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you’ve previously authorized?"</string>
+ <string name="dev_settings_warning_title" msgid="7244607768088540165">"Allow development settings?"</string>
+ <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
+ <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
+ <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behavior."</string>
+ <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
+ <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Allow ringtones on the phone to be played on Bluetooth headsets"</string>
+ <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
+ <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
+ <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
+ <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Set HDCP checking behavior"</string>
+ <string name="debug_debugging_category" msgid="6781250159513471316">"Debugging"</string>
+ <string name="debug_app" msgid="8349591734751384446">"Select debug app"</string>
+ <string name="debug_app_not_set" msgid="718752499586403499">"No debug application set"</string>
+ <string name="debug_app_set" msgid="2063077997870280017">"Debugging application: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="select_application" msgid="5156029161289091703">"Select application"</string>
+ <string name="no_application" msgid="2813387563129153880">"Nothing"</string>
+ <string name="wait_for_debugger" msgid="1202370874528893091">"Wait for debugger"</string>
+ <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Debugged application waits for debugger to attach before executing"</string>
+ <string name="telephony_monitor_switch" msgid="1764958220062121194">"Telephony Monitor"</string>
+ <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"TelephonyMonitor will collect logs when it detects a problem with telephony/modem functionality and prompt notification to user to file a bug"</string>
+ <string name="debug_input_category" msgid="1811069939601180246">"Input"</string>
+ <string name="debug_drawing_category" msgid="6755716469267367852">"Drawing"</string>
+ <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Hardware accelerated rendering"</string>
+ <string name="media_category" msgid="4388305075496848353">"Media"</string>
+ <string name="debug_monitoring_category" msgid="7640508148375798343">"Monitoring"</string>
+ <string name="strict_mode" msgid="1938795874357830695">"Strict mode enabled"</string>
+ <string name="strict_mode_summary" msgid="142834318897332338">"Flash screen when apps do long operations on main thread"</string>
+ <string name="pointer_location" msgid="6084434787496938001">"Pointer location"</string>
+ <string name="pointer_location_summary" msgid="840819275172753713">"Screen overlay showing current touch data"</string>
+ <string name="show_touches" msgid="2642976305235070316">"Show taps"</string>
+ <string name="show_touches_summary" msgid="6101183132903926324">"Show visual feedback for taps"</string>
+ <string name="show_screen_updates" msgid="5470814345876056420">"Show surface updates"</string>
+ <string name="show_screen_updates_summary" msgid="2569622766672785529">"Flash entire window surfaces when they update"</string>
+ <string name="show_hw_screen_updates" msgid="5036904558145941590">"Show GPU view updates"</string>
+ <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"Flash views inside windows when drawn with the GPU"</string>
+ <string name="show_hw_layers_updates" msgid="5645728765605699821">"Show hardware layers updates"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"Flash hardware layers green when they update"</string>
+ <string name="debug_hw_overdraw" msgid="2968692419951565417">"Debug GPU overdraw"</string>
+ <string name="debug_hw_renderer" msgid="7568529019431785816">"Set GPU Renderer"</string>
+ <string name="disable_overlays" msgid="2074488440505934665">"Disable HW overlays"</string>
+ <string name="disable_overlays_summary" msgid="3578941133710758592">"Always use GPU for screen compositing"</string>
+ <string name="simulate_color_space" msgid="6745847141353345872">"Simulate color space"</string>
+ <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Enable OpenGL traces"</string>
+ <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Disable USB audio routing"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Disable automatic routing to USB audio peripherals"</string>
+ <string name="debug_layout" msgid="5981361776594526155">"Show layout bounds"</string>
+ <string name="debug_layout_summary" msgid="2001775315258637682">"Show clip bounds, margins, etc."</string>
+ <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Force RTL layout direction"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Force screen layout direction to RTL for all locales"</string>
+ <string name="force_hw_ui" msgid="6426383462520888732">"Force GPU rendering"</string>
+ <string name="force_hw_ui_summary" msgid="5535991166074861515">"Force use of GPU for 2d drawing"</string>
+ <string name="force_msaa" msgid="7920323238677284387">"Force 4x MSAA"</string>
+ <string name="force_msaa_summary" msgid="9123553203895817537">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
+ <string name="show_non_rect_clip" msgid="505954950474595172">"Debug non-rectangular clip operations"</string>
+ <string name="track_frame_time" msgid="6146354853663863443">"Profile GPU rendering"</string>
+ <string name="window_animation_scale_title" msgid="6162587588166114700">"Window animation scale"</string>
+ <string name="transition_animation_scale_title" msgid="387527540523595875">"Transition animation scale"</string>
+ <string name="animator_duration_scale_title" msgid="3406722410819934083">"Animator duration scale"</string>
+ <string name="overlay_display_devices_title" msgid="5364176287998398539">"Simulate secondary displays"</string>
+ <string name="debug_applications_category" msgid="4206913653849771549">"Apps"</string>
+ <string name="immediately_destroy_activities" msgid="1579659389568133959">"Don’t keep activities"</string>
+ <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"Destroy every activity as soon as the user leaves it"</string>
+ <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string>
+ <string name="show_all_anrs" msgid="28462979638729082">"Show all ANRs"</string>
+ <string name="show_all_anrs_summary" msgid="641908614413544127">"Show App Not Responding dialog for background apps"</string>
+ <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string>
+ <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
+ <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
+ <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be resizable"</string>
+ <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
+ <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
+ <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
+ <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
+ <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren’t currently protected"</string>
+ <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
+ <string name="local_backup_password_toast_success" msgid="582016086228434290">"New backup password set"</string>
+ <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"New password and confirmation don’t match"</string>
+ <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Failure setting backup password"</string>
+ <string-array name="color_mode_names">
+ <item msgid="2425514299220523812">"Vibrant (default)"</item>
+ <item msgid="8446070607501413455">"Natural"</item>
+ <item msgid="6553408765810699025">"Standard"</item>
+ </string-array>
+ <string-array name="color_mode_descriptions">
+ <item msgid="4979629397075120893">"Enhanced colors"</item>
+ <item msgid="8280754435979370728">"Natural colors as seen by the eye"</item>
+ <item msgid="5363960654009010371">"Colors optimized for digital content"</item>
+ </string-array>
+ <string name="inactive_apps_title" msgid="1317817863508274533">"Inactive apps"</string>
+ <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inactive. Tap to toggle."</string>
+ <string name="inactive_app_active_summary" msgid="4174921824958516106">"Active. Tap to toggle."</string>
+ <string name="runningservices_settings_title" msgid="8097287939865165213">"Running services"</string>
+ <string name="runningservices_settings_summary" msgid="854608995821032748">"View and control currently running services"</string>
+ <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
+ <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
+ <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"This choice is no longer valid. Try again."</string>
+ <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
+ <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
+ <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
+ <string name="title_convert_fbe" msgid="1263622876196444453">"Converting to file based encryption"</string>
+ <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Convert data partition to file based encryption.\n !!Warning!! This will erase all your data.\n This feature is alpha, and may not work correctly.\n Press \'Wipe and convert…\' to continue."</string>
+ <string name="button_convert_fbe" msgid="5152671181309826405">"Wipe and convert…"</string>
+ <string name="picture_color_mode" msgid="4560755008730283695">"Picture color mode"</string>
+ <string name="picture_color_mode_desc" msgid="1141891467675548590">"Use sRGB"</string>
+ <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Disabled"</string>
+ <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"Monochromacy"</string>
+ <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Deuteranomaly (red-green)"</string>
+ <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomaly (red-green)"</string>
+ <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomaly (blue-yellow)"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Color correction"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
+ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">^1</xliff:g> left"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">^1</xliff:g> left until fully charged"</string>
+ <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">^1</xliff:g> left"</string>
+ <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">^1</xliff:g> left based on your usage"</string>
+ <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">^1</xliff:g> - about <xliff:g id="TIME">^2</xliff:g> left"</string>
+ <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">^1</xliff:g> - about <xliff:g id="TIME">^2</xliff:g> left based on your usage"</string>
+ <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> left"</string>
+ <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g> until fully charged"</string>
+ <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">^1</xliff:g> - <xliff:g id="TIME">^2</xliff:g>"</string>
+ <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
+ <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
+ <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
+ <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
+ <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
+ <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
+ <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
+ <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
+ <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
+ <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
+ <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
+ <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
+ <string name="home" msgid="3256884684164448244">"Settings Home"</string>
+ <string-array name="battery_labels">
+ <item msgid="8494684293649631252">"0%"</item>
+ <item msgid="8934126114226089439">"50%"</item>
+ <item msgid="1286113608943010849">"100%"</item>
+ </string-array>
+ <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
+ <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+ <string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string>
+ <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+ <string name="retail_demo_reset_message" msgid="118771671364131297">"Enter password to perform factory reset in demo mode"</string>
+ <string name="retail_demo_reset_next" msgid="8356731459226304963">"Next"</string>
+ <string name="retail_demo_reset_title" msgid="696589204029930100">"Password required"</string>
+ <string name="active_input_method_subtypes" msgid="3596398805424733238">"Active input methods"</string>
+ <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Use system languages"</string>
+ <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
+ <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 830d5ab..8eff989 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado a Wi-Fi, sin conexión a Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punto de acceso está completo temporalmente"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conexión a través de %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponible a través de %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dos barras de Wi-Fi"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de Wi-Fi"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Señal de Wi-Fi excelente"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Red abierta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Red segura"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"SO Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicaciones eliminadas"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicaciones y usuarios eliminados"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando."</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"El administrador habilitó esta opción"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 102ea05..4ac4b27 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conexión sin Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto de acceso temporalmente lleno"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conectado a través de %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponible a través de %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dos barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Señal de Wi-Fi al máximo."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Red abierta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Red segura"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"SO Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicaciones eliminadas"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Usuarios y aplicaciones eliminados"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Habilitada por el administrador"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 4c889f4..28a2a596 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ühendatud, Interneti-ühendus puudub"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pääsupunkt on ajutiselt täis"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Ühendatud operaatori %1$s kaudu"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Saadaval operaatori %1$s kaudu"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Väga aeglane"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Aeglane"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Hea"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WiFi: kaks pulka."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi: kolm pulka."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WiFi-signaal on tugev."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Avatud võrk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Turvaline võrk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Eemaldatud rakendused"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Eemaldatud rakendused ja kasutajad"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laadimine"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ei lae"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Juhib administraator"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Administraatori lubatud"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index e81acf8..4e19b99 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Konektatuta, ez dago Interneteko konexiorik"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Sarbide-puntua beteta dago aldi baterako"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s bidez konektatuta"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s bidez erabilgarri"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Oso motela"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Motela"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ados"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi sarearen bi barra."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi sarearen hiru barra."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi sarearen seinalea osoa."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Sare irekia"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sare segurua"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android sistema eragilea"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Kendutako aplikazioak"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Kendutako aplikazioak eta erabiltzaileak"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"kargatzen"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ez da kargatzen ari"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administratzaileak kontrolatzen du"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Administratzaileak gaitu du"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9d790b8..15facd8 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"متصل از طریق %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"در دسترس از طریق %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصل، بدون اینترنت"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ظرفیت نقطه دسترسی موقتاً تکمیل شده است"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"متصل ازطریق %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"در دسترس ازطریق %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"بسیار آهسته"</string>
<string name="speed_label_slow" msgid="813109590815810235">"آهسته"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"تأیید"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"دو نوار برای Wi‑Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"سه نوار برای Wi‑Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"قدرت سیگنال Wi‑Fi کامل است."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"شبکه باز"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"شبکه ایمن"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"سیستم عامل Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"برنامههای حذف شده"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"برنامهها و کاربران حذف شده"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"درحال شارژ شدن"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"شارژ نمیشود"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمیشود"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"توسط سرپرست سیستم کنترل میشود"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"فعالشده توسط سرپرست"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 2d0ecc6..59ba137 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Yhdistetty, ei internetyhteyttä."</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Yhteyspiste tilapäisesti täynnä"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Yhdistetty, verkko: %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Käytettävissä, verkko: %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Hyvin hidas"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Hidas"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-signaali – kaksi palkkia"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-signaali – kolme palkkia"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Vahva Wi-Fi-signaali"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Avoin verkko"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Suojattu verkko"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android-käyttöjärjestelmä"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Poistetut sovellukset"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Poistetut sovellukset ja käyttäjät"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ladataan"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ei laturissa"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Järjestelmänvalvojan käyttöön ottama"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 431426e..201984c 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Le point d\'accès est temporairement plein"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connecté par %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Accessible par %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi : deux barres."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi : trois barres."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi : signal complet."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Réseau ouvert"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Réseau sécurisé"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Système d\'exploitation Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Applications supprimées"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Applications et utilisateurs supprimés"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charge en cours…"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"en cours de charge"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"N\'est pas en charge"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index caa143f8..281e957 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Point d\'accès temporairement plein"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connecté via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponible via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Correct"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Signal Wi-Fi moyen"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Signal Wi-Fi bon"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Signal Wi-Fi excellent"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Réseau ouvert"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Réseau sécurisé"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Plate-forme Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Applications supprimées"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Applications et utilisateurs supprimés"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"chargement…"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Pas en charge"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 994a327..3311a5f 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado, pero sen Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"O punto de acceso está temporalmente cheo"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conectado a través de %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dispoñible a través de %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Moi lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dúas barras de wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal completo de wifi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rede aberta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Rede segura"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"SO Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicacións eliminadas"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicacións e usuarios eliminados"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Non se está cargando"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Opción controlada polo administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Activado polo administrador"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index c11f98c..b931fd1 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ઍક્સેસ પૉઇન્ટ અસ્થાયીરૂપે ભરાયેલ છે"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s દ્વારા ઉપલબ્ધ"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ખૂબ જ ધીમી"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ધીમી"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ઓકે"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi બે બાર."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ત્રણ બાર."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"પૂર્ણ Wifi સિગ્નલ."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"નેટવર્ક ખોલો"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"સુરક્ષિત નેટવર્ક"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"દૂર કરેલી ઍપ્લિકેશનો"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"દૂર કરેલી ઍપ્લિકેશનો અને વપરાશકર્તાઓ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ચાર્જ થઈ રહ્યું નથી"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"વ્યવસ્થાપકે સક્ષમ કરેલ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 465482b..b383b2e 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्ट किया गया, इंटरनेट नहीं"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"एक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s के ज़रिए कनेक्ट"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s के ज़रिए उपलब्ध"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"अत्यधिक धीमी"</string>
<string name="speed_label_slow" msgid="813109590815810235">"धीमी"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठीक"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"वाई-फ़ाई की दो पट्टी मिल रही हैं."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"वाई-फ़ाई की एक पट्टी मिल रही है."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"पूरे वाई-फ़ाई सिग्नल मिल रहे हैं."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"खुला नेटवर्क"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"निकाले गए ऐप्स"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ऐप्स और उपयोगकर्ताओं को निकालें"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज किया जा रहा है"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज नहीं हो रही है"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"व्यवस्थापक द्वारा नियंत्रित"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"व्यवस्थापक ने सक्षम किया है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 1ff5b41..0b86615 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano, bez interneta"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna je točka privremeno puna"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Povezano putem mreže %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dostupno putem mreže %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Vrlo sporo"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sporo"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"U redu"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi signal ima dva stupca."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi signal ima tri stupca."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal je pun."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Otvorena mreža"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sigurna mreža"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolira administrator"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 8434090..b6e55ec 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Csatlakozva, nincs internetelérés"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"A hozzáférési pont átmenetileg megtelt"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Csatlakozva a következőn keresztül: %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Elérhető a következőn keresztül: %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Nagyon lassú"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lassú"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Rendben"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-jel: két sáv."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-jel: három sáv."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-jel: teljes."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Nyílt hálózat"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Biztonságos hálózat"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Eltávolított alkalmazások"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Eltávolított alkalmazások és felhasználók"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"töltés"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nem tölt"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Rendszergazda által irányítva"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"A rendszergazda bekapcsolta"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 1d12405..e44e387 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Կապակցված է առանց համացանցի"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Հասանելիության կետը ժամանակավորապես լիքն է"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Միացված է %1$s-ի միջոցով"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Հասանելի է %1$s-ի միջոցով"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Շատ դանդաղ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Դանդաղ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Հաստատել"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-ի ուժգնությունը՝ երկու գիծ:"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-ի ուժգնությունը՝ երեք գիծ:"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-ի ազդանշանը ուժեղ է:"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Բաց ցանց"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Անվտանգ ցանց"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Հեռացված ծրագրեր"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Հեռացված հավելվածներն ու օգտատերերը"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"լիցքավորում"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Չի լիցքավորվում"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Միացված է ադմինիստրատորի կողմից"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 6fbc0a0..89da94b 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tersambung, tidak ada internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh untuk sementara"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Tersambung melalui %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Tersedia melalui %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Oke"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dua baris"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tiga baris."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinyal Wi-Fi penuh."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Jaringan terbuka"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Jaringan aman"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplikasi dihapus"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplikasi dan pengguna yang dihapus"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengisi daya baterai"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengisi daya"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikontrol oleh admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Diaktifkan oleh admin"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 72f71f5..c5bca1c 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tengt, enginn internetaðgangur"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Aðgangsstaður tímabundið fullur"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Tengt í gegnum %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Í boði í gegnum %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Mjög hægt"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Hægt"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Í lagi"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: Tvö strik."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: Þrjú strik."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Fullur Wi-Fi sendistyrkur."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Opið net"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Öruggt net"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android stýrikerfið"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Fjarlægð forrit"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Fjarlægð forrit og notendur"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"í hleðslu"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ekki í hleðslu"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Stjórnað af kerfisstjóra"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Gert virkt af kerfisstjóra"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 3003597..cd6b785 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connesso senza Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto di accesso momentaneamente al completo"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connesso tramite %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponibile tramite %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Molto lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: due barre."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre barre."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Segnale Wi-Fi completo."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rete aperta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Rete protetta"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Sistema operativo Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Applicazioni rimosse"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"App e utenti rimossi"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"in carica"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Non in carica"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Gestita dall\'amministratore"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Attivata dall\'amministratore"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 0368a04..3c0bf6b 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"מחובר דרך %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"זמינה דרך %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"מחובר. אין אינטרנט"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"נקודת הגישה מלאה באופן זמני"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"מחובר לרשת של %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"זמינה דרך %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"איטית מאוד"</string>
<string name="speed_label_slow" msgid="813109590815810235">"איטית"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"אישור"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"שני פסים של Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"שלושה פסים של Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"אות Wi-Fi מלא."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"רשת פתוחה"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"רשת מאובטחת"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"אפליקציות שהוסרו"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"אפליקציות ומשתמשים שהוסרו"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"מופעל על ידי מנהל המכשיר"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 952c4fb..713f796 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"接続済み、インターネットは利用できません"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"アクセス ポイントが一時的にいっぱいです"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s 経由で接続済み"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s 経由で使用可能"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"とても遅い"</string>
<string name="speed_label_slow" msgid="813109590815810235">"遅い"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fiはレベル2です。"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fiはレベル3です。"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fiの電波はフルです。"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"オープンネットワーク"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"保護されたネットワーク"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"削除したアプリケーション"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"削除されたアプリとユーザー"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電しています"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"充電していません"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"充電していません"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<!-- String.format failed for translation -->
<!-- no translation found for battery_info_status_full (2824614753861462808) -->
<skip />
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index fbdd1b6..ff27523 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"დაკავშირებულია, ინტერნეტის გარეშე"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"წვდომის წერტილი დროებით გადატვირთულია"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s-ით დაკავშირებული"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"ხელმისაწვდომია %1$s-ით"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ძალიან ნელი"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ნელი"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"კარგი"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WiFi სიგნალი ორ ზოლზეა."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi სიგნალი სამ ზოლზეა."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WiFi სიგნალი სრულია."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ღია ქსელი"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"დაცული ქსელი"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"აპების წაშლა"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"წაშლილი აპები და მომხმარებლები"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"იტენება"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"არ იტენება"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"იმართება ადმინისტრატორის მიერ"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"ჩართულია ადმინისტრატორის მიერ"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a071c23..5c07139 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Қосылған, интернет жоқ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Кіру нүктесі уақытша бос емес"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s арқылы қосылды"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s арқылы қолжетімді"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Өте баяу"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Баяу"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Жарайды"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi сигналы — екі жолақ."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi сигналы — үш жолақ."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi сигналы толық."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Ашық желі"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Қауіпсіз желі"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android операциялық жүйесі"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Алынған қолданбалар"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Алынған қолданбалар және пайдаланушылар"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарядталуда"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Зарядталу орындалып жатқан жоқ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Әкімші басқарады"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Әкімші қосқан"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index e3b8482..45687bf 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"បានភ្ជាប់ ប៉ុន្តែគ្មានអ៊ីនធឺណិតទេ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ចំណុចចូលប្រើពេញជាបណ្តោះអាសន្ន"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"បានភ្ជាប់តាមរយៈ %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"មានតាមរយៈ %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"យឺតណាស់"</string>
<string name="speed_label_slow" msgid="813109590815810235">"យឺត"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"យល់ព្រម"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi ពីរកាំ"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi បីកាំ"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"សេវា Wifi ពេញ"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"បើកបណ្ដាញ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"បណ្តាញដែលមានសុវត្ថិភាព"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"ប្រព័ន្ធប្រតិបត្តិការ Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"កម្មវិធីដែលបានលុប"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"បានលុបកម្មវិធី និងអ្នកប្រើ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូលថ្ម"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"កំពុងសាកថ្ម"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"មិនកំពុងបញ្ចូលថ្ម"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិនបញ្ចូលថ្ម"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"បើកដោយអ្នកគ្រប់គ្រង"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 6442140..0b39e26 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ, ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ಪ್ರವೇಶ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ನಿಧಾನ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ಸರಿ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ವೈಫೈ ಎರಡು ಪಟ್ಟಿಗಳು."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ವೈಫೈ ಮೂರು ಪಟ್ಟಿಗಳು."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ವೈಫೈ ಸಿಗ್ನಲ್ ಪೂರ್ತಿ ಇದೆ."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ನೆಟ್ವರ್ಕ್ ತೆರೆಯಿರಿ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ಸುರಕ್ಷಿತ ನೆಟ್ವರ್ಕ್"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ತೆಗೆದುಹಾಕಲಾದ ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 42fbdcc..9bd7111 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"인터넷을 사용하지 않고 연결됨"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"액세스 포인트가 일시적으로 가득 참"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s을(를) 통해 연결됨"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s을(를) 통해 사용 가능"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"매우 느림"</string>
<string name="speed_label_slow" msgid="813109590815810235">"느림"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"확인"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 신호 막대가 두 개입니다."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 신호 막대가 세 개입니다."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 신호가 강합니다."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"개방형 네트워크"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"보안 네트워크"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"삭제된 앱"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"삭제된 앱 및 사용자"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"충전 중"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"충전 안함"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"관리자가 제어"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"관리자가 사용 설정함"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index cce8ad4..f26ed8c 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Туташып турат, Интернет жок"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Туташуу түйүнү убактылуу толуп калды"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s аркылуу туташты"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s аркылуу иштейт"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Өтө жай"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Жай"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Жарайт"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi: эки таякча."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi: үч таякча."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi: күчтүү сигнал."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Ачык тармак"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Коопсуз тармак"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Алынып салынган колдонмолор"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Өчүрүлгөн колдонмолор жана колдонуучулар"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"кубатталууда"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Кубат алган жок"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Администратор тарабынан көзөмөлдөнөт"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Администратор иштетип койгон"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 6c459803..3500664 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ມີໃຫ້ຜ່ານ %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"ເຊື່ອມຕໍ່ແລ້ວ, ບໍ່ມີອິນເຕີເນັດ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ຈຸດການເຂົ້າເຖິງເຕັມຊົ່ວຄາວ"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"ໃຊ້ໄດ້ຜ່ານ %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ຊ້າຫຼາຍ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ຊ້າ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ຕົກລົງ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ສັນຍານ Wi-Fi ສອງຂີດ."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ສາມຂີດ."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ສັນຍານ Wi-Fi ເຕັມ"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ເຄືອຂ່າຍເປີດ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ເຄືອຂ່າຍເຂົ້າລະຫັດ"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ແອັບຯທີ່ຖືກລຶບອອກແລ້ວ"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ລຶບແອັບຯ ແລະຜູ່ໃຊ້ແລ້ວ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ບໍ່ໄດ້ສາກໄຟ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"ຜູ້ເບິ່ງແຍງລະບົບເປີດໃຫ້ໃຊ້ແລ້ວ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3c16a59..889f312 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Prisijungta, nėra interneto"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prieigos taškas laikinai visiškai užimtas"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Prisijungta naudojant „%1$s“"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Pasiekiama naudojant „%1$s“"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Labai lėtas"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lėtas"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Gerai"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dvi „Wi-Fi“ signalo juostos."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Trys „Wi-Fi“ signalo juostos."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Stiprus „Wi-Fi“ signalas."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Atviras tinklas"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Saugus tinklas"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"„Android“ OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Pašalintos programos"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Pašalintos programos ir naudotojai"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"įkraunama"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nekraunama"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Valdo administratorius"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Įgalino administratorius"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index e02b1b4..512ebaa 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Savienots, nav piekļuves internetam"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Piekļuves punkts īslaicīgi ir pilns"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Savienojums izveidots, izmantojot %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Pieejams, izmantojot %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Ļoti lēns"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lēns"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Labi"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: divas joslas"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: trīs joslas"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Pilna piekļuve Wi-Fi signālam"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Atvērts tīkls"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Drošs tīkls"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Noņemtās lietotnes"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Noņemtās lietotnes un lietotāji"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"notiek uzlāde"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenotiek uzlāde"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolē administrators"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Iespējoja administrators"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 920c38f..0dbaae2 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Поврзана, нема интернет"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пристапната точка привремено е преоптоварена"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Поврзано преку %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Достапно преку %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Многу бавна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Во ред"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Две црти на Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Три црти на Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Полн сигнал на Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Отворена мрежа"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Заклучена мрежа"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Оперативен систем Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Отстранети апликации"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Отстранети апликации и корисници"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"се полни"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не се полни"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Полна"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролирано од администраторот"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Овозможено од администраторот"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index b2f7fc0..84c1279 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇന്റർനെറ്റില്ല"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ആക്സസ് പോയിന്റ് താൽക്കാലികമായി നിറഞ്ഞിരിക്കുന്നു"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s വഴി ലഭ്യം"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"കുറഞ്ഞ വേഗത്തിൽ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ശരി"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"വൈഫൈ സിഗ്നൽ രണ്ട് ബാറുകൾ."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"വൈഫൈ സിഗ്നൽ മൂന്ന് ബാറുകൾ."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"വൈഫൈ മികച്ച സിഗ്നൽ."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ഓപ്പൺ നെറ്റ്വര്ക്ക്"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"സുരക്ഷിത നെറ്റ്വര്ക്ക്"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"നീക്കംചെയ്ത അപ്ലിക്കേഷനുകൾ"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"നീക്കംചെയ്ത അപ്ലിക്കേഷനുകളും ഉപയോക്താക്കളും"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ചാർജ് ചെയ്യുന്നു"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"അഡ്മിൻ നിയന്ത്രിക്കുന്നത്"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"അഡ്മിൻ പ്രവർത്തനക്ഷമമാക്കി"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index cd4d44f..8f4b695 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Холбогдсон, интернэт байхгүй байна"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Хандах цэг түр хугацаанд дүүрсэн байна"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s-р холбогдсон"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s-р боломжтой"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Маш удаан"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Удаан"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ЗА"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi сүлжээний дохио хоёр баганатай байна."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi сүлжээний дохио гурван баганатай байна."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi-н дохио дүүрэн байна."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Нээлттэй сүлжээ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Аюулгүй сүлжээ"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Андройд OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Арилгасан апп-ууд"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Арилгасан апп-ууд болон хэрэглэгчид"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"цэнэглэж байна"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Цэнэглэхгүй байна"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Админ удирдсан"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Админ идэвхжүүлсэн"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 16dd560..4f7cff7 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्ट केले"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्ध"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्ट केले, इंटरनेट नाही"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ने कनेक्ट केले"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ने उपलब्ध"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"खूप हळू"</string>
<string name="speed_label_slow" msgid="813109590815810235">"हळू"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठीक आहे"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"वाय फाय दोन बार."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"वाय फाय तीन बार."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"वाय फाय सिग्नल संपूर्ण आहे."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"नेटवर्क उघडा"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"काढलेले अॅप्स"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अॅप्स आणि वापरकर्ते"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज होत आहे"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज होत नाही"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकाने नियंत्रित केलेले"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकाने सक्षम केलेले"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 840ca8e9..eef4dd5 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Disambungkan, tiada Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh buat sementara waktu"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Disambungkan melalui %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Tersedia melalui %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Perlahan"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Perlahan"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dua bar."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tiga bar."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Isyarat Wi-Fi penuh."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rangkaian terbuka"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Rangkaian selamat"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Apl dialih keluar"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Apl dan pengguna yang dialih keluar"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengecas"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengecas"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikawal oleh pentadbir"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Didayakan oleh pentadbir"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index a32797e..6aad3aa 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"ချိတ်ဆက်ထားသည်၊ အင်တာနက်မရှိ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ကွန်ရက်ချိတ်ဆက်မှု ယာယီပြည့်နေသည်"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s မှတစ်ဆင့် ရနိုင်သည်"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"အလွန်နှေး"</string>
<string name="speed_label_slow" msgid="813109590815810235">"နှေး"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi ၂ ဘား"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi ၃ ဘား"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi အပြည့်ရှိ"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"အများသုံး ကွန်ရက်"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"လုံခြုံသည့် ကွန်ရက်"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android စနစ်"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ဖယ်ရှားထားသော အက်ပ်များ"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ဖယ်ရှားထားသော အပလီကေးရှင်းနှင့် သုံးစွဲသူများ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"အားသွင်းမနေပါ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"စီမံခန့်ခွဲသူက ဖွင့်ထားသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 7995259..756c2fc 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilkoblet – ingen Internett-forbindelse"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Tilgangspunktet er midlertidig fullt"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Tilkoblet via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Tilgjengelig via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veldig treg"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Treg"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-signal med to stolper."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-signal med tre stolper."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-signalet er ved full styrke."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Åpent nettverk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sikkert nettverk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android-operativsystem"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Fjernede apper"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Fjernede apper og brukere"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"lader"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Lader ikke"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrollert av administratoren"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Slått på av administratoren"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 6ea0e50..03d39af 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"जडित, इन्टरनेट चलेको छैन"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"पहुँचसम्बन्धी स्थान अस्थायी रूपमा भरिएको छ"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s मार्फत जडान गरियो"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s मार्फत उपलब्ध"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"धेरै ढिलो"</string>
<string name="speed_label_slow" msgid="813109590815810235">"बिस्तारै"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठीक छ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi दुई पट्टि।"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi तीन बारहरू।"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"पूर्ण Wi-Fi सिंग्नल।"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"खुला नेटवर्क"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"एन्ड्रोइड OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"हटाइएका अनुप्रयोगहरू"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"अनुप्रयोगहरू र प्रयोगकर्ताहरू हटाइयो।"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज हुँदै"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज भइरहेको छैन"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकद्वारा नियन्त्रित"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकद्वारा सक्षम पारिएको छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index f1a7648..6ca23af 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbonden, geen internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt tijdelijk vol"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Verbonden via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Beschikbaar via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Zeer langzaam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langzaam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Redelijk"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi: twee streepjes."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi: drie streepjes."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifii-signaal is op volledige sterkte."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open netwerk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Beveiligd netwerk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android-besturingssysteem"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Verwijderde apps"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Verwijderde apps en gebruikers"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"opladen"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Wordt niet opgeladen"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ingesteld door beheerder"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Ingeschakeld door beheerder"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 8efe422..3a43495 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈਟ ਨਹੀਂ"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ਪਹੁੰਚ ਪੁਆਇੰਟ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਸੰਪੂਰਨ ਰੁਝੇਂਵੇਂ ਵਿੱਚ ਹੈ"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ਬਹੁਤ ਹੌਲੀ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ਹੌਲੀ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ਠੀਕ ਹੈ"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi ਦੋ ਬਾਰ।"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ਤਿੰਨ ਬਾਰ।"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi ਸਿਗਨਲ ਪੂਰਾ।"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ਖੁੱਲ੍ਹਾ ਨੈੱਟਵਰਕ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ਹਟਾਏ ਗਏ ਐਪਸ"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ਹਟਾਏ ਗਏ ਐਪਸ ਅਤੇ ਉਪਭੋਗਤਾ"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 9b05d6b..a635a85 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Połączono, brak internetu"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punkt dostępu jest tymczasowo zajęty"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Połączono przez: %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Dostępna przez: %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Bardzo wolna"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Wolna"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: dwa paski."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: trzy paski."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: pełna moc sygnału."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Sieć otwarta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Sieć zabezpieczona"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"System operacyjny Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Usunięte aplikacje"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Usunięte aplikacje i użytkownicy"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ładowanie"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nie podłączony"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolowane przez administratora"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Włączone przez administratora"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 7e6e2dc..2e1855b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -41,6 +41,8 @@
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conectado via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponível via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -354,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 514dfd1..02af40f 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -41,6 +41,8 @@
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ligado, sem Internet"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Ligado através de %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponível através de %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -354,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"a carregar…"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está a carregar"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Ativada pelo administrador"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index a444b59..e3f287b 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -190,9 +190,9 @@
</string-array>
<string-array name="animator_duration_scale_entries">
<item msgid="6039901060648228241">"Animação desativada"</item>
- <item msgid="1138649021950863198">"Escala de animação 5x"</item>
+ <item msgid="1138649021950863198">"Escala de animação 0,5x"</item>
<item msgid="4394388961370833040">"Escala de animação 1x"</item>
- <item msgid="8125427921655194973">"Escala de animação 1.5 x"</item>
+ <item msgid="8125427921655194973">"Escala de animação 1,5x"</item>
<item msgid="3334024790739189573">"Escala de animação 2x"</item>
<item msgid="3170120558236848008">"Escala de animação 5x"</item>
<item msgid="1069584980746680398">"Escala de animação 10x"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 0d06ef6..2e1855b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conectado via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponível via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Duas barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Três barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal Wi-Fi cheio."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rede aberta"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Rede segura"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Sistema operacional Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Apps removidos"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Apps e usuários removidos"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index f722806..3ecec0e 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectată, fără internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punctul de acces este temporar plin"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Conectată prin %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Disponibilă prin %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Foarte lentă"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lentă"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Bine"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Semnal Wi-Fi: două bare."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Semnal Wi-Fi: trei bare."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Semnal Wi-Fi: complet."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rețea nesecurizată"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Securizați rețeaua"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Sistem de operare Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicații eliminate"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicații și utilizatori eliminați"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"se încarcă"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nu se încarcă"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlată de administrator"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Activat de administrator"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index a1ad9c3..c35a1e1 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Подключено, без Интернета"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"К точке доступа подключено слишком много устройств"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Подключено к %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Доступно через %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Очень медленная"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Медленная"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: два деления"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: три деления"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: надежный сигнал"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Открытая сеть"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Защищенная сеть"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"ОС Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Удаленные приложения"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Удаленные приложения и пользователи"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряжается"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряжается"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролируется администратором"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Включено администратором"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 257e27e..5e8011a 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"සම්බන්ධයි, අන්තර්ජාලය නැත"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ප්රවේශ ලක්ෂ්ය තාවකාලිකව පිරී ඇත"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s හරහා සම්බන්ධ විය"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ඉතා මන්දගාමී"</string>
<string name="speed_label_slow" msgid="813109590815810235">"මන්දගාමී"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"හරි"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi තීරු දෙකයි."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi තීරු තුනයි."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi සංඥාව පිරී ඇත."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"විවෘත ජාලය"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ආරක්ෂිත ජාලය"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ඉවත් කළ යෙදුම්"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"යෙදුම් සහ පරිශීලකයින් ඉවත් කරන ලදි"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ආරෝපණය වේ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ආරෝපණය නොවේ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"පරිපාලක විසින් සබල කර ඇත"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index dd2b793..b81fee1 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Pripojené, žiadny internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prístupový bod je dočasne plný"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Pripojené prostredníctvom operátora %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"K dispozícii prostredníctvom operátora %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veľmi nízka"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Nízka"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve čiarky signálu Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri čiarky signálu Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Plný signál Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Otvorená sieť"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Zabezpečená sieť"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Odstránené aplikácie"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Odstránené aplikácie a používatelia"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíjanie"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíja sa"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ovládané správcom"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Povolené správcom"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 70b84e3..4f3bce1 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Vzpostavljena povezava, brez interneta"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Dostopna točka je trenutno zasedena"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Vzpostavljena povezava prek: %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Na voljo prek: %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Zelo počasna"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Počasna"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"V redu"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve črtici signala Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri črtice signala Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Poln signal Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Odprto omrežje"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Varno omrežje"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Odstranjene aplikacije"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Odstranjene aplikacije in uporabniki"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"polnjenje"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Se ne polni"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Nadzira skrbnik"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Omogočil skrbnik"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index e1c36ed..0558c36 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"U lidh, nuk ka internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pika e qasjes është përkohësisht plot"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"E lidhur përmes %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"E disponueshme përmes %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Shumë e ulët"</string>
<string name="speed_label_slow" msgid="813109590815810235">"E ngadaltë"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Në rregull"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi ka dy vija."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre vija."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi ka sinjal të plotë."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Rrjet i hapur"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Rrjet i sigurt"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Sistemi operativ Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplikacionet e hequra"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplikacionet dhe përdoruesit e hequr"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"po ngarkohet"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Nuk po ngarkohet"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolluar nga administratori"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Aktivizuar nga administratori"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 6a6a9b9..f1506d2 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Веза је успостављена, нема интернета"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Приступна тачка је привремено заузета"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Повезано преко %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Доступно преко %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Веома спора"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Спора"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Потврди"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi сигнал има две црте."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi сигнал има три црте."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi сигнал је најјачи."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Отворена мрежа"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Безбедна мрежа"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android ОС"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Уклоњене апликације"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Уклоњене апликације и корисници"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"пуни се"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не пуни се"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролише администратор"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Омогућио је администратор"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 29c87cc..97511cf 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ansluten, inget internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Åtkomstpunkten har inga platser över för tillfället"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Anslutet via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Tillgängligt via %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Mycket långsam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Långsam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Okej"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: två staplar."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre staplar."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Full signalstyrka för Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Öppet nätverk"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Säkert nätverk"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Operativsystemet Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Borttagna appar"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Borttagna appar och användare"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laddas"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Laddar inte"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Strys av administratören"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Aktiverad av administratör"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 05dfd17..6e4e85e 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Imeunganishwa, hakuna Intaneti"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Lango la mtandao lina shughuli nyingi kwa sasa"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Imeunganishwa kupitia %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Inapatikana kupitia %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Polepole Sana"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Polepole"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Sawa"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Vipima mtandao viwili vya Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Vipima mtandao vitatu vya Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Nguvu kamili ya mtandao wa Wifi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Mtandao unaotumiwa na mtu yeyote"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Mtandao salama"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"OS ya Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Programu zilizoondolewa"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Watumiaji na programu ziilizoondolewa"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"inachaji"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Haichaji"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Imedhibitiwa na msimamizi"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Imewashwa na msimamizi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index f85cca3..e707596 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"இணைக்கப்பட்டது, இணையம் இல்லை"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"தற்காலிகமாக அணுகல் புள்ளி நிரம்பியுள்ளது"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s வழியாக இணைக்கப்பட்டது"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s வழியாகக் கிடைக்கிறது"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"மிகவும் வேகம் குறைவானது"</string>
<string name="speed_label_slow" msgid="813109590815810235">"வேகம் குறைவு"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"சரி"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"வைஃபை சிக்னல்: இரண்டு கோடுகள்."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"வைஃபை சிக்னல்: மூன்று கோடுகள்."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"வைஃபை சிக்னல் முழுமையாக உள்ளது."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"கடவுச்சொல் தேவைப்படாத திறந்த நெட்வொர்க்"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"கடவுச்சொல் தேவைப்படும் பாதுகாப்பான நெட்வொர்க்"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"அகற்றப்பட்ட பயன்பாடுகள்"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"அகற்றப்பட்ட பயன்பாடுகள் மற்றும் பயனர்கள்"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஏற்றப்படுகிறது"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"சார்ஜாகிறது"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"சார்ஜ் செய்யப்படவில்லை"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"நிர்வாகி இயக்கியுள்ளார்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index aa331a5..20e8931 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"కనెక్ట్ చేయబడింది, ఇంటర్నెట్ లేదు"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ప్రాప్యత పాయింట్ తాత్కాలికంగా పూర్తయింది"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"చాలా నెమ్మది"</string>
<string name="speed_label_slow" msgid="813109590815810235">"నెమ్మది"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"సరే"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi సిగ్నల్ రెండు బార్లు ఉంది."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi సిగ్నల్ మూడు బార్లు ఉంది."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi సిగ్నల్ పూర్తిగా ఉంది."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ఓపెన్ నెట్వర్క్"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"సురక్షిత నెట్వర్క్"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"తీసివేయబడిన అనువర్తనాలు"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"తీసివేయబడిన అనువర్తనాలు మరియు వినియోగదారులు"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ఛార్జ్ కావడం లేదు"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"నిర్వాహకులు ప్రారంభించారు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 1582da5..ef21584 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"เชื่อมต่อแล้ว ไม่พบอินเทอร์เน็ต"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"จุดเข้าใช้งานเต็มชั่วคราว"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"พร้อมใช้งานผ่านทาง %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ช้ามาก"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ช้า"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ตกลง"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"สัญญาณ Wi-Fi 2 ขีด"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"สัญญาณ Wi-Fi 3 ขีด"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"สัญญาณ Wi-Fi เต็ม"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"เครือข่ายแบบเปิด"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"เครือข่ายที่ปลอดภัย"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"ระบบปฏิบัติการของ Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"แอปพลิเคชันที่นำออก"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"แอปพลิเคชันและผู้ใช้ที่นำออก"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"กำลังชาร์จ"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"ไม่ได้ชาร์จ"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"เปิดใช้โดยผู้ดูแลระบบ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6b0fad9..51630dac 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Nakakonekta, walang Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pansamantalang puno ang access point"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Nakakonekta sa pamamagitan ng %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available sa pamamagitan ng %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Napakabagal"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Mabagal"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"May dalawang bar ang Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"May tatlong bar ang Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Puno ang signal ng Wifi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Bukas na network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Ligtas na network"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Mga inalis na app"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Mga inalis na apps at user"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nagcha-charge"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Hindi nagcha-charge"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pinapamahalaan ng admin"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Na-enable ng admin"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index b883c5fc..f2f94a2 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Bağlı, İnternet yok"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Erişim noktası geçici olarak dolu"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s üzerinden bağlı"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s üzerinden kullanılabilir"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Çok Yavaş"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Tamam"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Kablosuz sinyal gücü iki çubuk."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Kablosuz sinyal gücü üç çubuk."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Kablosuz sinyal gücü tam."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Açık ağ"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Güvenli ağ"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Kaldırılan uygulamalar"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Kaldırılmış kullanıcılar ve uygulamalar"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"şarj oluyor"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Şarj olmuyor"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Yönetici tarafından denetleniyor"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Yönetici tarafından etkinleştirildi"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 24bb553..a8705e7 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -138,25 +138,25 @@
</string-array>
<string-array name="select_logd_size_titles">
<item msgid="8665206199209698501">"Вимкнено"</item>
- <item msgid="1593289376502312923">"64 Кб"</item>
- <item msgid="487545340236145324">"256 Кб"</item>
- <item msgid="2423528675294333831">"1 Мб"</item>
- <item msgid="180883774509476541">"4 Мб"</item>
- <item msgid="2803199102589126938">"16 Мб"</item>
+ <item msgid="1593289376502312923">"64 КБ"</item>
+ <item msgid="487545340236145324">"256 КБ"</item>
+ <item msgid="2423528675294333831">"1 МБ"</item>
+ <item msgid="180883774509476541">"4 МБ"</item>
+ <item msgid="2803199102589126938">"16 МБ"</item>
</string-array>
<string-array name="select_logd_size_lowram_titles">
<item msgid="6089470720451068364">"Вимкнено"</item>
- <item msgid="4622460333038586791">"64 Кб"</item>
- <item msgid="2212125625169582330">"256 Кб"</item>
- <item msgid="1704946766699242653">"1 Мб"</item>
+ <item msgid="4622460333038586791">"64 КБ"</item>
+ <item msgid="2212125625169582330">"256 КБ"</item>
+ <item msgid="1704946766699242653">"1 МБ"</item>
</string-array>
<string-array name="select_logd_size_summaries">
<item msgid="6921048829791179331">"Вимкнено"</item>
- <item msgid="2969458029344750262">"Буфер журналу: 64 Кб"</item>
- <item msgid="1342285115665698168">"Буфер журналу: 256 Кб"</item>
- <item msgid="1314234299552254621">"Буфер журналу: 1 Мб"</item>
- <item msgid="3606047780792894151">"Буфер журналу: 4 Мб"</item>
- <item msgid="5431354956856655120">"Буфер журналу: 16 Мб"</item>
+ <item msgid="2969458029344750262">"Буфер журналу: 64 КБ"</item>
+ <item msgid="1342285115665698168">"Буфер журналу: 256 КБ"</item>
+ <item msgid="1314234299552254621">"Буфер журналу: 1 МБ"</item>
+ <item msgid="3606047780792894151">"Буфер журналу: 4 МБ"</item>
+ <item msgid="5431354956856655120">"Буфер журналу: 16 МБ"</item>
</string-array>
<string-array name="select_logpersist_titles">
<item msgid="1744840221860799971">"Вимкнено"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index de35869..7f329ce 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Під’єднано, але немає доступу до Інтернету"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точка доступу тимчасово переповнена"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Під’єднано через мережу %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Доступ через мережу %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Дуже повільна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Повільна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -104,18 +105,16 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Дві смужки сигналу Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Три смужки сигналу Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Максимальний сигнал Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Відкрита мережа"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Захищена мережа"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"ОС Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Видалені програми"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Видалені програми та користувачі"</string>
- <string name="tether_settings_title_usb" msgid="6688416425801386511">"Прив\'язка USB"</string>
+ <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB-модем"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"Порт. точка дост."</string>
- <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Прив\'язка Bluetooth"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth-модем"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Прив\'язка"</string>
- <string name="tether_settings_title_all" msgid="8356136101061143841">"Режим модема"</string>
+ <string name="tether_settings_title_all" msgid="8356136101061143841">"Точка доступу й модем"</string>
<string name="managed_user_title" msgid="8109605045406748842">"Усі робочі додатки"</string>
<string name="user_guest" msgid="8475274842845401871">"Гість"</string>
<string name="unknown" msgid="1592123443519355854">"Невідомо"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Заряджається"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряджається"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряджається"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Керується адміністратором"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Увімкнено адміністратором"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 186ae02..9d37602 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"منسلک بذریعہ %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"دستیاب بذریعہ %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"منسلک، انٹرنیٹ نہیں ہے"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"رسائی پوائنٹ عارضی طور پر فُل ہے"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"منسلک بذریعہ %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"دستیاب بذریعہ %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"بہت سست"</string>
<string name="speed_label_slow" msgid="813109590815810235">"سست"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ٹھیک ہے"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi دو بارز۔"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi تین بارز۔"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi سگنل پورا ہے۔"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"اوپن نیٹ ورک"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"محفوظ نیٹ ورک"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ہٹائی گئی ایپس"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ہٹائی گئی ایپس اور صارفین"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"چارج نہیں ہو رہا ہے"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"کنٹرول کردہ بذریعہ منتظم"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"منتظم کی طرف سے فعال کردہ"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 3bcda0c..872d121 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ulangan, lekin internet aloqasi yo‘q"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Internet kirish nuqtasi vaqtinchalik to‘lgan"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s orqali ulangan"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"%1$s orqali ishlaydi"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Juda sekin"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sekin"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: ikkita ustun"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: uchta ustun"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: signal to‘liq"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Ochiq tarmoq"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Xavfsiz tarmoq"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"O‘chirilgan ilovalar"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"O‘chirib tashlangan ilova va foydalanuvchilar"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"quvvat olmoqda"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvat olmayapti"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administrator tomonidan boshqariladi"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Administrator tomonidan yoqilgan"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index b22f7fe..1c9f917 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Đã kết nối, không có Internet"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Điểm truy cập tạm thời đã đạt đến giới hạn số lượng thiết bị truy cập."</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Được kết nối qua %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Có sẵn qua %1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Rất chậm"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Chậm"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Khá tốt"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Tín hiệu Wi-Fi hai vạch."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tín hiệu Wi-Fi ba vạch."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Tín hiệu Wi-Fi đủ."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Mạng mở"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Mạng bảo mật"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Hệ điều hành Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Ứng dụng đã xóa"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Ứng dụng và người dùng bị xóa"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"đang sạc"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Hiện không sạc"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Do quản trị viên kiểm soát"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Kích hoạt bởi quản trị viên"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 21c4a94..c164347 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"已连接,但无法访问互联网"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"接入点暂时满载"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"已通过%1$s连接"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"可通过%1$s连接"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"很慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WLAN 信号强度为两格。"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WLAN 信号强度为三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WLAN 信号满格。"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"开放网络"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"安全网络"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android 操作系统"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"已删除的应用"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"已删除的应用和用户"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充电"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"未在充电"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"由管理员控制"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"已被管理员启用"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 21d4170..4fadad1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有互聯網"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時已滿"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"已透過 %1$s 連線"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"可透過 %1$s 連線"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 訊號兩格。"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 訊號三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 訊號滿格。"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"開放式網絡"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"安全網絡"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android 作業系統"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"已移除的應用程式"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"已移除的應用程式和使用者"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充電"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 746efd1..ed21c9a 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有網際網路"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時滿載"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"已透過 %1$s 連線"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"可透過 %1$s 使用"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"確定"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 訊號強度兩格。"</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 訊號強度三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 訊號強度滿格。"</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"開放式網路"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"安全網路"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android 作業系統"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"移除的應用程式"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"已移除的應用程式和使用者"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電中"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9dcd1e3..b598297 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -40,8 +40,9 @@
<string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Kuxhumekile, ayikho i-inthanethi"</string>
- <!-- no translation found for wifi_ap_unable_to_handle_new_sta (5348824313514404541) -->
- <skip />
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Iphoyinti lokufinyelela ligcwele okwesikhashana"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Kuxhumeke nge-%1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Iyatholakala nge-%1$s"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Phansi kakhulu"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Phansi"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"KULUNGILE"</string>
@@ -104,10 +105,8 @@
<string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Amabha amabili we-Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Amabha amathathu we-Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Isiginali ye-Wifi igcwele."</string>
- <!-- no translation found for accessibility_wifi_security_type_none (1223747559986205423) -->
- <skip />
- <!-- no translation found for accessibility_wifi_security_type_secured (862921720418885331) -->
- <skip />
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Vula inethiwekhi"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Inethiwekhi evikelekile"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"I-Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Izinhlelo zokusebenza zisusiwe"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Izinhelo zokusebenza nabasebenzisi abasusiwe"</string>
@@ -357,7 +356,8 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"iyashaja"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Ayishaji"</string>
- <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string>
+ <!-- no translation found for battery_info_status_not_charging (8523453668342598579) -->
+ <skip />
<string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kulawulwa umqondisi"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Kunikwe amandla umlawuli"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 259446a..fd5b70e 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -100,6 +100,11 @@
<!-- Summary for networks failing to connect due to association rejection status 17, AP full -->
<string name="wifi_ap_unable_to_handle_new_sta">Access point temporarily full</string>
+ <!-- Status message of Wi-Fi when it is connected to a Carrier Network. [CHAR LIMIT=NONE] -->
+ <string name="connected_via_carrier">Connected via %1$s</string>
+ <!-- Status message of Wi-Fi when an available network is a carrier network. [CHAR LIMIT=NONE] -->
+ <string name="available_via_carrier">Available via %1$s</string>
+
<!-- Speed label for very slow network speed -->
<string name="speed_label_very_slow">Very Slow</string>
<!-- Speed label for slow network speed -->
@@ -874,7 +879,7 @@
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
<string name="battery_info_status_discharging">Not charging</string>
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
- <string name="battery_info_status_not_charging">Not charging</string>
+ <string name="battery_info_status_not_charging">Plugged in, can\'t charge right now</string>
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
<string name="battery_info_status_full">Full</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index d07da93..7d4bc83 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -97,7 +97,6 @@
// Pairing broadcasts
addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
- addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());
// Fine-grained state broadcasts
addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
@@ -344,24 +343,6 @@
}
}
- private class PairingCancelHandler implements Handler {
- public void onReceive(Context context, Intent intent, BluetoothDevice device) {
- if (device == null) {
- Log.e(TAG, "ACTION_PAIRING_CANCEL with no EXTRA_DEVICE");
- return;
- }
- CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
- if (cachedDevice == null) {
- Log.e(TAG, "ACTION_PAIRING_CANCEL with no cached device");
- return;
- }
- int errorMsg = R.string.bluetooth_pairing_error_message;
- if (context != null && cachedDevice != null) {
- Utils.showError(context, cachedDevice.getName(), errorMsg);
- }
- }
- }
-
private class DockEventHandler implements Handler {
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
// Remove if unpair device upon undocking
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
index f9dc0e4..00f32b2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -91,28 +91,25 @@
// Shared prefs keys for storing dismissed state.
// Index into current dismissed state.
- @VisibleForTesting
- static final String DISMISS_INDEX = "_dismiss_index";
public static final String SETUP_TIME = "_setup_time";
private static final String IS_DISMISSED = "_is_dismissed";
// Default dismiss control for smart suggestions.
- private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
+ private static final String DEFAULT_SMART_DISMISS_CONTROL = "0";
private final Context mContext;
private final List<SuggestionCategory> mSuggestionList;
private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
private final SharedPreferences mSharedPrefs;
- private final String mSmartDismissControl;
-
+ private final String mDefaultDismissControl;
public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml,
- String smartDismissControl) {
+ String defaultDismissControl) {
this(
context,
sharedPrefs,
(List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
- smartDismissControl);
+ defaultDismissControl);
}
public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
@@ -124,11 +121,11 @@
Context context,
SharedPreferences sharedPrefs,
List<SuggestionCategory> suggestionList,
- String smartDismissControl) {
+ String defaultDismissControl) {
mContext = context;
mSuggestionList = suggestionList;
mSharedPrefs = sharedPrefs;
- mSmartDismissControl = smartDismissControl;
+ mDefaultDismissControl = defaultDismissControl;
}
public SuggestionList getSuggestions(boolean isSmartSuggestionEnabled) {
@@ -161,25 +158,16 @@
return suggestionList;
}
- public boolean dismissSuggestion(Tile suggestion) {
- return dismissSuggestion(suggestion, false);
- }
-
/**
* Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
* be disabled.
*/
- public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
- String keyBase = suggestion.intent.getComponent().flattenToShortString();
- int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
- String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
- if (dismissControl == null || parseDismissString(dismissControl).length == index) {
- return true;
- }
+ public boolean dismissSuggestion(Tile suggestion) {
+ final String keyBase = suggestion.intent.getComponent().flattenToShortString();
mSharedPrefs.edit()
.putBoolean(keyBase + IS_DISMISSED, true)
.commit();
- return false;
+ return true;
}
@VisibleForTesting
@@ -357,32 +345,29 @@
@VisibleForTesting
boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
- if (dismissControl == null) {
- return false;
- }
String keyBase = suggestion.intent.getComponent().flattenToShortString();
if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
mSharedPrefs.edit()
.putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
.commit();
}
- // Default to dismissed, so that we can have suggestions that only first appear after
- // some number of days.
- if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
- return false;
- }
- int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
- int[] dismissRules = parseDismissString(dismissControl);
- if (dismissRules.length <= index) {
+ // Check if it's already manually dismissed
+ final boolean isDismissed = mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, false);
+ if (isDismissed) {
return true;
}
- int currentDismiss = dismissRules[index];
- long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
- if (System.currentTimeMillis() >= time) {
+ if (dismissControl == null) {
+ return false;
+ }
+ // Parse when suggestion should first appear. return true to artificially hide suggestion
+ // before then.
+ int firstAppearDay = parseDismissString(dismissControl);
+ long firstAppearDayInMs = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0),
+ firstAppearDay);
+ if (System.currentTimeMillis() >= firstAppearDayInMs) {
// Dismiss timeout has passed, undismiss it.
mSharedPrefs.edit()
.putBoolean(keyBase + IS_DISMISSED, false)
- .putInt(keyBase + DISMISS_INDEX, index + 1)
.commit();
return false;
}
@@ -394,18 +379,18 @@
return startTime + days;
}
- private int[] parseDismissString(String dismissControl) {
- String[] dismissStrs = dismissControl.split(",");
- int[] dismisses = new int[dismissStrs.length];
- for (int i = 0; i < dismissStrs.length; i++) {
- dismisses[i] = Integer.parseInt(dismissStrs[i]);
- }
- return dismisses;
+ /**
+ * Parse the first int from a string formatted as "0,1,2..."
+ * The value means suggestion should first appear on Day X.
+ */
+ private int parseDismissString(String dismissControl) {
+ final String[] dismissStrs = dismissControl.split(",");
+ return Integer.parseInt(dismissStrs[0]);
}
private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
if (isSmartSuggestionEnabled) {
- return mSmartDismissControl;
+ return mDefaultDismissControl;
} else {
return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index a814a9f..b8c5aca 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -37,6 +37,7 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
@@ -59,7 +60,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -120,6 +123,10 @@
*/
private final ConcurrentHashMap<String, ScanResult> mScanResultCache =
new ConcurrentHashMap<String, ScanResult>(32);
+
+ /** Map of BSSIDs to speed values for individual ScanResults. */
+ private final Map<String, Integer> mScanResultScores = new HashMap<>();
+
/** Maximum age of scan results to hold onto while actively scanning. **/
private static final long MAX_SCAN_RESULT_AGE_MS = 15000;
@@ -134,6 +141,9 @@
static final String KEY_CONFIG = "key_config";
static final String KEY_FQDN = "key_fqdn";
static final String KEY_PROVIDER_FRIENDLY_NAME = "key_provider_friendly_name";
+ static final String KEY_IS_CARRIER_AP = "key_is_carrier_ap";
+ static final String KEY_CARRIER_AP_EAP_TYPE = "key_carrier_ap_eap_type";
+ static final String KEY_CARRIER_NAME = "key_carrier_name";
static final AtomicInteger sLastId = new AtomicInteger(0);
/**
@@ -191,6 +201,13 @@
private String mFqdn;
private String mProviderFriendlyName;
+ private boolean mIsCarrierAp = false;
+ /**
+ * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP.
+ */
+ private int mCarrierApEapType = WifiEnterpriseConfig.Eap.NONE;
+ private String mCarrierName = null;
+
public AccessPoint(Context context, Bundle savedState) {
mContext = context;
mConfig = savedState.getParcelable(KEY_CONFIG);
@@ -227,7 +244,18 @@
if (savedState.containsKey(KEY_PROVIDER_FRIENDLY_NAME)) {
mProviderFriendlyName = savedState.getString(KEY_PROVIDER_FRIENDLY_NAME);
}
+ if (savedState.containsKey(KEY_IS_CARRIER_AP)) {
+ mIsCarrierAp = savedState.getBoolean(KEY_IS_CARRIER_AP);
+ }
+ if (savedState.containsKey(KEY_CARRIER_AP_EAP_TYPE)) {
+ mCarrierApEapType = savedState.getInt(KEY_CARRIER_AP_EAP_TYPE);
+ }
+ if (savedState.containsKey(KEY_CARRIER_NAME)) {
+ mCarrierName = savedState.getString(KEY_CARRIER_NAME);
+ }
update(mConfig, mInfo, mNetworkInfo);
+
+ // Do not evict old scan results on initial creation
updateRssi();
updateSeen();
mId = sLastId.incrementAndGet();
@@ -280,9 +308,14 @@
this.mNetworkInfo = that.mNetworkInfo;
this.mScanResultCache.clear();
this.mScanResultCache.putAll(that.mScanResultCache);
+ this.mScanResultScores.clear();
+ this.mScanResultScores.putAll(that.mScanResultScores);
this.mId = that.mId;
this.mSpeed = that.mSpeed;
this.mIsScoredNetworkMetered = that.mIsScoredNetworkMetered;
+ this.mIsCarrierAp = that.mIsCarrierAp;
+ this.mCarrierApEapType = that.mCarrierApEapType;
+ this.mCarrierName = that.mCarrierName;
}
/**
@@ -392,6 +425,7 @@
*/
boolean update(WifiNetworkScoreCache scoreCache, boolean scoringUiEnabled) {
boolean scoreChanged = false;
+ mScanResultScores.clear();
if (scoringUiEnabled) {
scoreChanged = updateScores(scoreCache);
}
@@ -407,6 +441,18 @@
int oldSpeed = mSpeed;
mSpeed = Speed.NONE;
+ for (ScanResult result : mScanResultCache.values()) {
+ ScoredNetwork score = scoreCache.getScoredNetwork(result);
+ if (score == null) {
+ continue;
+ }
+
+ int speed = score.calculateBadge(result.level);
+ mScanResultScores.put(result.BSSID, speed);
+ mSpeed = Math.max(mSpeed, speed);
+ }
+
+ // set mSpeed to the connected ScanResult if the AccessPoint is the active network
if (isActive() && mInfo != null) {
NetworkKey key = new NetworkKey(new WifiKey(
AccessPoint.convertToQuotedString(ssid), mInfo.getBSSID()));
@@ -414,15 +460,6 @@
if (score != null) {
mSpeed = score.calculateBadge(mInfo.getRssi());
}
- } else {
- for (ScanResult result : mScanResultCache.values()) {
- ScoredNetwork score = scoreCache.getScoredNetwork(result);
- if (score == null) {
- continue;
- }
- // TODO(sghuman): Rename calculateBadge API
- mSpeed = Math.max(mSpeed, score.calculateBadge(result.level));
- }
}
if(WifiTracker.sVerboseLogging) {
@@ -460,10 +497,6 @@
}
private void evictOldScanResults() {
- if (WifiTracker.sStaleScanResults) {
- // Do not evict old scan results unless we are scanning and have fresh results.
- return;
- }
long nowMs = SystemClock.elapsedRealtime();
for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) {
ScanResult result = iter.next();
@@ -527,12 +560,8 @@
* results, returning the best RSSI for all matching AccessPoints averaged with the previous
* value. If the access point is not connected and there are no scan results, the rssi will be
* set to {@link #UNREACHABLE_RSSI}.
- *
- * <p>Old scan results will be evicted from the cache when this method is invoked.
*/
private void updateRssi() {
- evictOldScanResults();
-
if (this.isActive()) {
return;
}
@@ -551,14 +580,8 @@
}
}
- /**
- * Updates {@link #mSeen} based on the scan result cache.
- *
- * <p>Old scan results will be evicted from the cache when this method is invoked.
- */
+ /** Updates {@link #mSeen} based on the scan result cache. */
private void updateSeen() {
- evictOldScanResults();
-
// TODO(sghuman): Set to now if connected
long seen = 0;
@@ -592,7 +615,7 @@
public String getSecurityString(boolean concise) {
Context context = mContext;
- if (mConfig != null && mConfig.isPasspoint()) {
+ if (isPasspoint() || isPasspointConfig()) {
return concise ? context.getString(R.string.wifi_security_short_eap) :
context.getString(R.string.wifi_security_eap);
}
@@ -658,6 +681,18 @@
return null;
}
+ public boolean isCarrierAp() {
+ return mIsCarrierAp;
+ }
+
+ public int getCarrierApEapType() {
+ return mCarrierApEapType;
+ }
+
+ public String getCarrierName() {
+ return mCarrierName;
+ }
+
public String getSavedNetworkSummary() {
WifiConfiguration config = mConfig;
if (config != null) {
@@ -700,6 +735,9 @@
// This is the active connection on passpoint
summary.append(getSummary(mContext, getDetailedState(),
false, config.providerFriendlyName));
+ } else if (isActive() && config != null && getDetailedState() == DetailedState.CONNECTED
+ && mIsCarrierAp) {
+ summary.append(String.format(mContext.getString(R.string.connected_via_carrier), mCarrierName));
} else if (isActive()) {
// This is the active connection on non-passpoint network
summary.append(getSummary(mContext, getDetailedState(),
@@ -733,6 +771,8 @@
}
} else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) {
summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider));
+ } else if (mIsCarrierAp) {
+ summary.append(String.format(mContext.getString(R.string.available_via_carrier), mCarrierName));
} else if (!isReachable()) { // Wifi out of range
summary.append(mContext.getString(R.string.wifi_not_in_range));
} else { // In range, not disabled.
@@ -813,8 +853,8 @@
*/
private String getVisibilityStatus() {
StringBuilder visibility = new StringBuilder();
- StringBuilder scans24GHz = null;
- StringBuilder scans5GHz = null;
+ StringBuilder scans24GHz = new StringBuilder();
+ StringBuilder scans5GHz = new StringBuilder();
String bssid = null;
long now = System.currentTimeMillis();
@@ -836,87 +876,55 @@
visibility.append(String.format("rx=%.1f", mInfo.rxSuccessRate));
}
- int rssi5 = WifiConfiguration.INVALID_RSSI;
- int rssi24 = WifiConfiguration.INVALID_RSSI;
- int num5 = 0;
- int num24 = 0;
+ int maxRssi5 = WifiConfiguration.INVALID_RSSI;
+ int maxRssi24 = WifiConfiguration.INVALID_RSSI;
+ final int maxDisplayedScans = 4;
+ int num5 = 0; // number of scanned BSSID on 5GHz band
+ int num24 = 0; // number of scanned BSSID on 2.4Ghz band
int numBlackListed = 0;
- int n24 = 0; // Number scan results we included in the string
- int n5 = 0; // Number scan results we included in the string
evictOldScanResults();
+
// TODO: sort list by RSSI or age
for (ScanResult result : mScanResultCache.values()) {
-
if (result.frequency >= LOWER_FREQ_5GHZ
&& result.frequency <= HIGHER_FREQ_5GHZ) {
// Strictly speaking: [4915, 5825]
- // number of known BSSID on 5GHz band
- num5 = num5 + 1;
+ num5++;
+
+ if (result.level > maxRssi5) {
+ maxRssi5 = result.level;
+ }
+ if (num5 <= maxDisplayedScans) {
+ scans5GHz.append(verboseScanResultSummary(result, bssid));
+ }
} else if (result.frequency >= LOWER_FREQ_24GHZ
&& result.frequency <= HIGHER_FREQ_24GHZ) {
// Strictly speaking: [2412, 2482]
- // number of known BSSID on 2.4Ghz band
- num24 = num24 + 1;
- }
+ num24++;
-
- if (result.frequency >= LOWER_FREQ_5GHZ
- && result.frequency <= HIGHER_FREQ_5GHZ) {
- if (result.level > rssi5) {
- rssi5 = result.level;
+ if (result.level > maxRssi24) {
+ maxRssi24 = result.level;
}
- if (n5 < 4) {
- if (scans5GHz == null) scans5GHz = new StringBuilder();
- scans5GHz.append(" \n{").append(result.BSSID);
- if (bssid != null && result.BSSID.equals(bssid)) scans5GHz.append("*");
- scans5GHz.append("=").append(result.frequency);
- scans5GHz.append(",").append(result.level);
- scans5GHz.append("}");
- n5++;
- }
- } else if (result.frequency >= LOWER_FREQ_24GHZ
- && result.frequency <= HIGHER_FREQ_24GHZ) {
- if (result.level > rssi24) {
- rssi24 = result.level;
- }
- if (n24 < 4) {
- if (scans24GHz == null) scans24GHz = new StringBuilder();
- scans24GHz.append(" \n{").append(result.BSSID);
- if (bssid != null && result.BSSID.equals(bssid)) scans24GHz.append("*");
- scans24GHz.append("=").append(result.frequency);
- scans24GHz.append(",").append(result.level);
- scans24GHz.append("}");
- n24++;
+ if (num24 <= maxDisplayedScans) {
+ scans24GHz.append(verboseScanResultSummary(result, bssid));
}
}
}
visibility.append(" [");
if (num24 > 0) {
visibility.append("(").append(num24).append(")");
- if (n24 <= 4) {
- if (scans24GHz != null) {
- visibility.append(scans24GHz.toString());
- }
- } else {
- visibility.append("max=").append(rssi24);
- if (scans24GHz != null) {
- visibility.append(",").append(scans24GHz.toString());
- }
+ if (num24 > maxDisplayedScans) {
+ visibility.append("max=").append(maxRssi24).append(",");
}
+ visibility.append(scans24GHz.toString());
}
visibility.append(";");
if (num5 > 0) {
visibility.append("(").append(num5).append(")");
- if (n5 <= 4) {
- if (scans5GHz != null) {
- visibility.append(scans5GHz.toString());
- }
- } else {
- visibility.append("max=").append(rssi5);
- if (scans5GHz != null) {
- visibility.append(",").append(scans5GHz.toString());
- }
+ if (num5 > maxDisplayedScans) {
+ visibility.append("max=").append(maxRssi5).append(",");
}
+ visibility.append(scans5GHz.toString());
}
if (numBlackListed > 0)
visibility.append("!").append(numBlackListed);
@@ -925,6 +933,28 @@
return visibility.toString();
}
+ @VisibleForTesting
+ /* package */ String verboseScanResultSummary(ScanResult result, String bssid) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(" \n{").append(result.BSSID);
+ if (result.BSSID.equals(bssid)) {
+ stringBuilder.append("*");
+ }
+ stringBuilder.append("=").append(result.frequency);
+ stringBuilder.append(",").append(result.level);
+ if (hasSpeed(result)) {
+ stringBuilder.append(",")
+ .append(getSpeedLabel(mScanResultScores.get(result.BSSID)));
+ }
+ stringBuilder.append("}");
+ return stringBuilder.toString();
+ }
+
+ private boolean hasSpeed(ScanResult result) {
+ return mScanResultScores.containsKey(result.BSSID)
+ && mScanResultScores.get(result.BSSID) != Speed.NONE;
+ }
+
/**
* Return whether this is the active connection.
* For ephemeral connections (networkId is invalid), this returns false if the network is
@@ -1022,6 +1052,9 @@
mScanResultCache.put(result.BSSID, result);
updateRssi();
mSeen = result.timestamp; // even if the timestamp is old it is still valid
+ mIsCarrierAp = result.isCarrierAp;
+ mCarrierApEapType = result.carrierApEapType;
+ mCarrierName = result.carrierName;
}
public void saveWifiState(Bundle savedState) {
@@ -1043,18 +1076,31 @@
if (mProviderFriendlyName != null) {
savedState.putString(KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
}
+ savedState.putBoolean(KEY_IS_CARRIER_AP, mIsCarrierAp);
+ savedState.putInt(KEY_CARRIER_AP_EAP_TYPE, mCarrierApEapType);
+ savedState.putString(KEY_CARRIER_NAME, mCarrierName);
}
public void setListener(AccessPointListener listener) {
mAccessPointListener = listener;
}
- boolean update(ScanResult result) {
+ /**
+ * Update the AP with the given scan result.
+ *
+ * @param result the ScanResult to add to the AccessPoint scan cache
+ * @param evictOldScanResults whether stale scan results should be removed
+ * from the cache during this update process
+ * @return true if the scan result update caused a change in state which would impact ranking
+ * or AccessPoint rendering (e.g. wifi level, security)
+ */
+ boolean update(ScanResult result, boolean evictOldScanResults) {
if (matches(result)) {
int oldLevel = getLevel();
/* Add or update the scan result for the BSSID */
mScanResultCache.put(result.BSSID, result);
+ if (evictOldScanResults) evictOldScanResults();
updateSeen();
updateRssi();
int newLevel = getLevel();
@@ -1071,6 +1117,12 @@
mAccessPointListener.onAccessPointChanged(this);
}
+ // The carrier info in the ScanResult is set by the platform based on the SSID and will
+ // always be the same for all matching scan results.
+ mIsCarrierAp = result.isCarrierAp;
+ mCarrierApEapType = result.carrierApEapType;
+ mCarrierName = result.carrierName;
+
return true;
}
return false;
@@ -1135,7 +1187,12 @@
@Nullable
String getSpeedLabel() {
- switch (mSpeed) {
+ return getSpeedLabel(mSpeed);
+ }
+
+ @Nullable
+ private String getSpeedLabel(int speed) {
+ switch (speed) {
case Speed.VERY_FAST:
return mContext.getString(R.string.speed_label_very_fast);
case Speed.FAST:
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
index bb51330..93bf3c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
@@ -23,6 +23,7 @@
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.os.Bundle;
+import android.support.annotation.Keep;
import com.android.settingslib.wifi.AccessPoint.Speed;
import java.util.ArrayList;
@@ -34,6 +35,7 @@
* applications. AccessPoints were designed to only be populated by the mechanisms of scan results
* and wifi configurations.
*/
+@Keep
public class TestAccessPointBuilder {
// match the private values in WifiManager
private static final int MIN_RSSI = -100;
@@ -51,14 +53,18 @@
private int mSecurity = AccessPoint.SECURITY_NONE;
private WifiConfiguration mWifiConfig;
private WifiInfo mWifiInfo;
+ private boolean mIsCarrierAp = false;
+ private String mCarrierName = null;
Context mContext;
private ArrayList<ScanResult> mScanResultCache;
+ @Keep
public TestAccessPointBuilder(Context context) {
mContext = context;
}
+ @Keep
public AccessPoint build() {
Bundle bundle = new Bundle();
@@ -81,12 +87,17 @@
}
bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity);
bundle.putInt(AccessPoint.KEY_SPEED, mSpeed);
+ bundle.putBoolean(AccessPoint.KEY_IS_CARRIER_AP, mIsCarrierAp);
+ if (mCarrierName != null) {
+ bundle.putString(AccessPoint.KEY_CARRIER_NAME, mCarrierName);
+ }
AccessPoint ap = new AccessPoint(mContext, bundle);
ap.setRssi(mRssi);
return ap;
}
+ @Keep
public TestAccessPointBuilder setActive(boolean active) {
if (active) {
mNetworkInfo = new NetworkInfo(
@@ -106,6 +117,7 @@
* <p>Side effect: if this AccessPoint was previously unreachable,
* setting the level will also make it reachable.
*/
+ @Keep
public TestAccessPointBuilder setLevel(int level) {
// Reversal of WifiManager.calculateSignalLevels
if (level == 0) {
@@ -120,11 +132,13 @@
return this;
}
+ @Keep
public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
mNetworkInfo = info;
return this;
}
+ @Keep
public TestAccessPointBuilder setRssi(int rssi) {
mRssi = rssi;
return this;
@@ -140,6 +154,7 @@
* Side effect: if the signal level was not previously set,
* making an AccessPoint reachable will set the signal to the minimum level.
*/
+ @Keep
public TestAccessPointBuilder setReachable(boolean reachable) {
if (reachable) {
// only override the mRssi if it hasn't been set yet
@@ -152,6 +167,7 @@
return this;
}
+ @Keep
public TestAccessPointBuilder setSaved(boolean saved){
if (saved) {
mNetworkId = 1;
@@ -161,26 +177,31 @@
return this;
}
+ @Keep
public TestAccessPointBuilder setSecurity(int security) {
mSecurity = security;
return this;
}
+ @Keep
public TestAccessPointBuilder setSsid(String newSsid) {
ssid = newSsid;
return this;
}
+ @Keep
public TestAccessPointBuilder setFqdn(String fqdn) {
mFqdn = fqdn;
return this;
}
+ @Keep
public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
mProviderFriendlyName = friendlyName;
return this;
}
+ @Keep
public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
mWifiInfo = info;
return this;
@@ -192,6 +213,7 @@
* <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
* AccessPoint a saved network.
*/
+ @Keep
public TestAccessPointBuilder setNetworkId(int networkId) {
mNetworkId = networkId;
return this;
@@ -206,4 +228,14 @@
mScanResultCache = scanResultCache;
return this;
}
+
+ public TestAccessPointBuilder setIsCarrierAp(boolean isCarrierAp) {
+ mIsCarrierAp = isCarrierAp;
+ return this;
+ }
+
+ public TestAccessPointBuilder setCarrierName(String carrierName) {
+ mCarrierName = carrierName;
+ return this;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 45032ce..a242570 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -147,7 +147,7 @@
Scanner mScanner;
@GuardedBy("mLock")
- static boolean sStaleScanResults = true;
+ private boolean mStaleScanResults = true;
public WifiTracker(Context context, WifiListener wifiListener,
boolean includeSaved, boolean includeScans) {
@@ -356,7 +356,7 @@
* <p>This should always be called when done with a WifiTracker (if startTracking was called) to
* ensure proper cleanup and prevent any further callbacks from occurring.
*
- * <p>Calling this method will set the {@link #sStaleScanResults} bit, which prevents
+ * <p>Calling this method will set the {@link #mStaleScanResults} bit, which prevents
* {@link WifiListener#onAccessPointsChanged()} callbacks from being invoked (until the bit
* is unset on the next SCAN_RESULTS_AVAILABLE_ACTION).
*/
@@ -374,7 +374,7 @@
mWorkHandler.removePendingMessages();
mMainHandler.removePendingMessages();
- sStaleScanResults = true;
+ mStaleScanResults = true;
}
}
@@ -480,7 +480,7 @@
/**
* Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first.
*
- * <p>Will not perform the update if {@link #sStaleScanResults} is true
+ * <p>Will not perform the update if {@link #mStaleScanResults} is true
*/
private void updateAccessPoints() {
List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
@@ -490,7 +490,7 @@
}
synchronized (mLock) {
- if(!sStaleScanResults) {
+ if(!mStaleScanResults) {
updateAccessPointsLocked(newScanResults, configs);
}
}
@@ -500,7 +500,7 @@
* Update the internal list of access points.
*
* <p>Do not called directly (except for forceUpdate), use {@link #updateAccessPoints()} which
- * respects {@link #sStaleScanResults}.
+ * respects {@link #mStaleScanResults}.
*/
@GuardedBy("mLock")
private void updateAccessPointsLocked(final List<ScanResult> newScanResults,
@@ -574,7 +574,8 @@
boolean found = false;
for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {
- if (accessPoint.update(result)) {
+ // We want to evict old scan results if are current results are not stale
+ if (accessPoint.update(result, !mStaleScanResults)) {
found = true;
break;
}
@@ -647,7 +648,8 @@
for (int i = 0; i < N; i++) {
if (cache.get(i).matches(result)) {
AccessPoint ret = cache.remove(i);
- ret.update(result);
+ // evict old scan results only if we have fresh results
+ ret.update(result, !mStaleScanResults);
return ret;
}
}
@@ -847,7 +849,7 @@
// Only notify listeners of changes if we have fresh scan results, otherwise the
// UI will be updated with stale results. We want to copy the APs regardless,
// for instances where forceUpdate was invoked by the caller.
- if (sStaleScanResults) {
+ if (mStaleScanResults) {
copyAndNotifyListeners(false /*notifyListeners*/);
} else {
copyAndNotifyListeners(true /*notifyListeners*/);
@@ -902,7 +904,7 @@
switch (msg.what) {
case MSG_UPDATE_ACCESS_POINTS:
if (msg.arg1 == CLEAR_STALE_SCAN_RESULTS) {
- sStaleScanResults = false;
+ mStaleScanResults = false;
}
updateAccessPoints();
break;
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 35c730e..ae59d37 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -35,6 +35,7 @@
import android.net.WifiKey;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiSsid;
@@ -73,6 +74,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
+ WifiTracker.sVerboseLogging = false;
}
@Test
@@ -256,7 +258,7 @@
scanResult.BSSID = "bssid";
scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
scanResult.capabilities = "";
- assertThat(ap.update(scanResult)).isTrue();
+ assertThat(ap.update(scanResult, true /* evict old scan results */)).isTrue();
assertThat(ap.getRssi()).isEqualTo(expectedRssi);
}
@@ -426,7 +428,6 @@
ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
verify(mockWifiNetworkScoreCache, times(2)).getScoredNetwork(key);
- verify(mockWifiNetworkScoreCache, never()).getScoredNetwork(any(ScanResult.class));
assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST);
}
@@ -444,6 +445,25 @@
}
@Test
+ public void testVerboseSummaryString_showsScanResultSpeedLabel() {
+ WifiTracker.sVerboseLogging = true;
+
+ Bundle bundle = new Bundle();
+ ArrayList<ScanResult> scanResults = buildScanResultCache();
+ bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults);
+ AccessPoint ap = new AccessPoint(mContext, bundle);
+
+ when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+ .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+ when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+ ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+ String summary = ap.verboseScanResultSummary(scanResults.get(0), null);
+
+ assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue();
+ }
+
+ @Test
public void testSummaryString_concatenatesSpeedLabel() {
AccessPoint ap = createAccessPointWithScanResultCache();
ap.update(new WifiConfiguration());
@@ -472,6 +492,75 @@
R.string.wifi_check_password_try_again));
}
+ @Test
+ public void testSummaryString_showsAvaiableViaCarrier() {
+ String carrierName = "Test Carrier";
+ ScanResult result = new ScanResult();
+ result.BSSID = "00:11:22:33:44:55";
+ result.capabilities = "EAP";
+ result.isCarrierAp = true;
+ result.carrierApEapType = WifiEnterpriseConfig.Eap.SIM;
+ result.carrierName = carrierName;
+
+ AccessPoint ap = new AccessPoint(mContext, result);
+ assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString(
+ R.string.available_via_carrier), carrierName));
+ assertThat(ap.isCarrierAp()).isEqualTo(true);
+ assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.SIM);
+ assertThat(ap.getCarrierName()).isEqualTo(carrierName);
+ }
+
+ @Test
+ public void testSummaryString_showsConnectedViaCarrier() {
+ int networkId = 123;
+ int rssi = -55;
+ String carrierName = "Test Carrier";
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = networkId;
+ WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setNetworkId(networkId);
+ wifiInfo.setRssi(rssi);
+
+ NetworkInfo networkInfo =
+ new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+ networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+
+ AccessPoint ap = new TestAccessPointBuilder(mContext)
+ .setNetworkInfo(networkInfo)
+ .setNetworkId(networkId)
+ .setRssi(rssi)
+ .setWifiInfo(wifiInfo)
+ .setIsCarrierAp(true)
+ .setCarrierName(carrierName)
+ .build();
+ assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString(
+ R.string.connected_via_carrier), carrierName));
+ }
+
+ @Test
+ public void testUpdateScanResultWithCarrierInfo() {
+ String ssid = "ssid";
+ AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build();
+ assertThat(ap.isCarrierAp()).isEqualTo(false);
+ assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.NONE);
+ assertThat(ap.getCarrierName()).isEqualTo(null);
+
+ int carrierApEapType = WifiEnterpriseConfig.Eap.SIM;
+ String carrierName = "Test Carrier";
+ ScanResult scanResult = new ScanResult();
+ scanResult.SSID = ssid;
+ scanResult.BSSID = "00:11:22:33:44:55";
+ scanResult.capabilities = "";
+ scanResult.isCarrierAp = true;
+ scanResult.carrierApEapType = carrierApEapType;
+ scanResult.carrierName = carrierName;
+ assertThat(ap.update(scanResult, true /* evictOldScanresults */)).isTrue();
+
+ assertThat(ap.isCarrierAp()).isEqualTo(true);
+ assertThat(ap.getCarrierApEapType()).isEqualTo(carrierApEapType);
+ assertThat(ap.getCarrierName()).isEqualTo(carrierName);
+ }
+
private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() {
Bundle attr1 = new Bundle();
attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 6ede55d..df6587e 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -137,7 +137,6 @@
private Looper mMainLooper;
private int mOriginalScoringUiSettingValue;
- private boolean mOriginalStaleScanResultsValue;
@Before
public void setUp() {
@@ -213,7 +212,6 @@
Settings.Global.NETWORK_SCORING_UI_ENABLED,
1 /* enabled */);
- mOriginalStaleScanResultsValue = WifiTracker.sStaleScanResults;
}
@After
@@ -222,8 +220,6 @@
InstrumentationRegistry.getTargetContext().getContentResolver(),
Settings.Global.NETWORK_SCORING_UI_ENABLED,
mOriginalScoringUiSettingValue);
-
- WifiTracker.sStaleScanResults = mOriginalStaleScanResultsValue;
}
private static ScanResult buildScanResult1() {
@@ -346,7 +342,10 @@
Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
- return createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+ WifiTracker tracker =
+ createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+ assertThat(tracker.isConnected()).isTrue();
+ return tracker;
}
private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
@@ -860,23 +859,26 @@
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
tracker.mReceiver.onReceive(mContext, intent);
+ waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
verify(mockWifiListener, times(1)).onConnectedChanged();
}
@Test
- public void onConnectedChangedCallback_shouldNBeInvokedWhenStateChanges() throws Exception {
+ public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
verify(mockWifiListener, times(1)).onConnectedChanged();
NetworkInfo networkInfo = new NetworkInfo(
ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
networkInfo.setDetailedState(
- NetworkInfo.DetailedState.DISCONNECTED, "dicconnected", "test");
+ NetworkInfo.DetailedState.DISCONNECTED, "disconnected", "test");
Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
tracker.mReceiver.onReceive(mContext, intent);
+ waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+ assertThat(tracker.isConnected()).isFalse();
verify(mockWifiListener, times(2)).onConnectedChanged();
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
new file mode 100644
index 0000000..abccd8d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+
+import java.util.List;
+
+/**
+ * Will be removed once robolectric is updated to O
+ */
+public class WifiNetworkScoreCache {
+
+ public WifiNetworkScoreCache(Context context, WifiNetworkScoreCache.CacheListener listener) {
+ }
+
+ public abstract static class CacheListener {
+ public CacheListener(Handler handler) {
+ }
+
+ void post(List updatedNetworks) {
+ }
+
+ public abstract void networkCacheUpdated(List updatedNetworks);
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
index 8391136..f6404a2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -83,7 +83,7 @@
mSuggestionParser = new SuggestionParser(mContext, mPrefs,
Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
- "0,0");
+ "0");
ResolveInfo info1 = TileUtilsTest.newInfo(true, null);
info1.activityInfo.packageName = "pkg";
@@ -109,17 +109,12 @@
}
@Test
- public void testDismissSuggestion_withoutSmartSuggestion() {
- assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
+ public void dismissSuggestion_shouldDismiss() {
+ assertThat(mSuggestionParser.dismissSuggestion(mSuggestion)).isTrue();
}
@Test
- public void testDismissSuggestion_withSmartSuggestion() {
- assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
- }
-
- @Test
- public void testGetSuggestions_withoutSmartSuggestions() {
+ public void testGetSuggestions_withoutSmartSuggestions_shouldDismiss() {
readAndDismissSuggestion(false);
mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
assertThat(mSuggestionsBeforeDismiss).hasSize(2);
@@ -128,11 +123,10 @@
}
@Test
- public void testGetSuggestions_withSmartSuggestions() {
+ public void testGetSuggestions_withSmartSuggestions_shouldDismiss() {
readAndDismissSuggestion(true);
assertThat(mSuggestionsBeforeDismiss).hasSize(2);
- assertThat(mSuggestionsAfterDismiss).hasSize(2);
- assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
+ assertThat(mSuggestionsAfterDismiss).hasSize(1);
}
@Test
@@ -191,19 +185,15 @@
}
@Test
- public void isSuggestionDismissed_mismatchRule_shouldDismiss() {
+ public void isSuggestionDismissed_dismissedSuggestion_shouldReturnTrue() {
final Tile suggestion = new Tile();
suggestion.metaData = new Bundle();
suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
// Dismiss suggestion when smart suggestion is not enabled.
- mSuggestionParser.dismissSuggestion(suggestion, false /* isSmartSuggestionEnabled */);
- final String suggestionKey = suggestion.intent.getComponent().flattenToShortString();
- // And point to last rule in dismiss control
- mPrefs.edit().putInt(suggestionKey + SuggestionParser.DISMISS_INDEX, 2).apply();
+ mSuggestionParser.dismissSuggestion(suggestion);
- // Turn on smart suggestion, and check if suggestion is enabled.
assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
.isTrue();
}
@@ -215,7 +205,7 @@
mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
- if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
+ if (mSuggestionParser.dismissSuggestion(suggestion)) {
RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
suggestion.intent.getComponent().getPackageName());
diff --git a/packages/SettingsProvider/res/values-en-rXC/defaults.xml b/packages/SettingsProvider/res/values-en-rXC/defaults.xml
new file mode 100644
index 0000000..b32199f3
--- /dev/null
+++ b/packages/SettingsProvider/res/values-en-rXC/defaults.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+ <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-en-rXC/strings.xml b/packages/SettingsProvider/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..e7abd48
--- /dev/null
+++ b/packages/SettingsProvider/res/values-en-rXC/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4567566098528588863">"Settings Storage"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 96f51c1..3d0147d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -34,6 +34,7 @@
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.BackupUtils;
import android.util.Log;
@@ -62,6 +63,9 @@
private static final boolean DEBUG = false;
private static final boolean DEBUG_BACKUP = DEBUG || false;
+ private static final byte[] NULL_VALUE = new byte[0];
+ private static final int NULL_SIZE = -1;
+
private static final String KEY_SYSTEM = "system";
private static final String KEY_SECURE = "secure";
private static final String KEY_GLOBAL = "global";
@@ -608,7 +612,7 @@
// Restore only the white list data.
int pos = 0;
- Map<String, String> cachedEntries = new HashMap<String, String>();
+ final ArrayMap<String, String> cachedEntries = new ArrayMap<>();
ContentValues contentValues = new ContentValues(2);
SettingsHelper settingsHelper = mSettingsHelper;
ContentResolver cr = getContentResolver();
@@ -616,28 +620,36 @@
final int whiteListSize = whitelist.length;
for (int i = 0; i < whiteListSize; i++) {
String key = whitelist[i];
- String value = cachedEntries.remove(key);
- // If the value not cached, let us look it up.
- if (value == null) {
+ String value = null;
+ boolean hasValueToRestore = false;
+ if (cachedEntries.indexOfKey(key) >= 0) {
+ value = cachedEntries.remove(key);
+ hasValueToRestore = true;
+ } else {
+ // If the value not cached, let us look it up.
while (pos < bytes) {
int length = readInt(settings, pos);
pos += INTEGER_BYTE_COUNT;
- String dataKey = length > 0 ? new String(settings, pos, length) : null;
+ String dataKey = length >= 0 ? new String(settings, pos, length) : null;
pos += length;
length = readInt(settings, pos);
pos += INTEGER_BYTE_COUNT;
- String dataValue = length > 0 ? new String(settings, pos, length) : null;
- pos += length;
+ String dataValue = null;
+ if (length >= 0) {
+ dataValue = new String(settings, pos, length);
+ pos += length;
+ }
if (key.equals(dataKey)) {
value = dataValue;
+ hasValueToRestore = true;
break;
}
cachedEntries.put(dataKey, dataValue);
}
}
- if (value == null) {
+ if (!hasValueToRestore) {
continue;
}
@@ -724,50 +736,56 @@
* @return The byte array of extracted values.
*/
private byte[] extractRelevantValues(Cursor cursor, String[] settings) {
- final int settingsCount = settings.length;
- byte[][] values = new byte[settingsCount * 2][]; // keys and values
if (!cursor.moveToFirst()) {
Log.e(TAG, "Couldn't read from the cursor");
return new byte[0];
}
+ final int nameColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.NAME);
+ final int valueColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
+
// Obtain the relevant data in a temporary array.
int totalSize = 0;
int backedUpSettingIndex = 0;
- Map<String, String> cachedEntries = new HashMap<String, String>();
+ final int settingsCount = settings.length;
+ final byte[][] values = new byte[settingsCount * 2][]; // keys and values
+ final ArrayMap<String, String> cachedEntries = new ArrayMap<>();
for (int i = 0; i < settingsCount; i++) {
- String key = settings[i];
- String value = cachedEntries.remove(key);
-
- final int nameColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.NAME);
- final int valueColumnIndex = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
+ final String key = settings[i];
// If the value not cached, let us look it up.
- if (value == null) {
+ String value = null;
+ boolean hasValueToBackup = false;
+ if (cachedEntries.indexOfKey(key) >= 0) {
+ value = cachedEntries.remove(key);
+ hasValueToBackup = true;
+ } else {
while (!cursor.isAfterLast()) {
- String cursorKey = cursor.getString(nameColumnIndex);
- String cursorValue = cursor.getString(valueColumnIndex);
+ final String cursorKey = cursor.getString(nameColumnIndex);
+ final String cursorValue = cursor.getString(valueColumnIndex);
cursor.moveToNext();
if (key.equals(cursorKey)) {
value = cursorValue;
+ hasValueToBackup = true;
break;
}
cachedEntries.put(cursorKey, cursorValue);
}
}
+ if (!hasValueToBackup) {
+ continue;
+ }
+
// Intercept the keys and see if they need special handling
value = mSettingsHelper.onBackupValue(key, value);
- if (value == null) {
- continue;
- }
// Write the key and value in the intermediary array.
- byte[] keyBytes = key.getBytes();
+ final byte[] keyBytes = key.getBytes();
totalSize += INTEGER_BYTE_COUNT + keyBytes.length;
values[backedUpSettingIndex * 2] = keyBytes;
- byte[] valueBytes = value.getBytes();
+ final byte[] valueBytes = (value != null) ? value.getBytes() : NULL_VALUE;
totalSize += INTEGER_BYTE_COUNT + valueBytes.length;
values[backedUpSettingIndex * 2 + 1] = valueBytes;
@@ -783,8 +801,13 @@
int pos = 0;
final int keyValuePairCount = backedUpSettingIndex * 2;
for (int i = 0; i < keyValuePairCount; i++) {
- pos = writeInt(result, pos, values[i].length);
- pos = writeBytes(result, pos, values[i]);
+ final byte[] value = values[i];
+ if (value != NULL_VALUE) {
+ pos = writeInt(result, pos, value.length);
+ pos = writeBytes(result, pos, value);
+ } else {
+ pos = writeInt(result, pos, NULL_SIZE);
+ }
}
return result;
}
diff --git a/packages/Shell/res/values-en-rXC/strings.xml b/packages/Shell/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..9e891f4
--- /dev/null
+++ b/packages/Shell/res/values-en-rXC/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Bug reports"</string>
+ <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string>
+ <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string>
+ <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string>
+ <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"The bug report will appear on the phone shortly"</string>
+ <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Select to share your bug report"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Select to share your bug report without a screenshot or wait for the screenshot to finish"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string>
+ <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"Bug reports contain data from the system\'s various log files, which may include data you consider sensitive (such as app-usage and location data). Only share bug reports with people and apps you trust."</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Don\'t show again"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string>
+ <string name="bugreport_unreadable_text" msgid="586517851044535486">"Bug report file could not be read"</string>
+ <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Couldn\'t add bug report details to zip file"</string>
+ <string name="bugreport_unnamed" msgid="2800582406842092709">"unnamed"</string>
+ <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
+ <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
+ <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot taken successfully."</string>
+ <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
+ <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Bug report <xliff:g id="ID">#%d</xliff:g> details"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"Filename"</string>
+ <string name="bugreport_info_title" msgid="2306030793918239804">"Bug title"</string>
+ <string name="bugreport_info_description" msgid="5072835127481627722">"Bug summary"</string>
+ <string name="save" msgid="4781509040564835759">"Save"</string>
+ <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Share Bug report"</string>
+</resources>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
index bb21fb3..1f633da 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
@@ -26,6 +26,8 @@
int VERSION = 1;
void showGlobalActions(GlobalActionsManager manager);
+ default void showShutdownUi(boolean isReboot, String reason) {
+ }
@ProvidesInterface(version = GlobalActionsManager.VERSION)
public interface GlobalActionsManager {
diff --git a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
deleted file mode 100644
index 82c01ef..0000000
--- a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
deleted file mode 100644
index 8c16930..0000000
--- a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
deleted file mode 100644
index 6a4d8a7..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
deleted file mode 100644
index 4c04ba2..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
deleted file mode 100644
index bd6c4df..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
deleted file mode 100644
index 1e4022e..0000000
--- a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:autoMirrored="true"
- android:height="24dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#ffffffff"
- android:pathData="M44.0,6.0L14.0,6.0c-1.4,0.0 -2.5,0.7 -3.2,1.8L0.0,24.0l10.8,16.2c0.7,1.1 1.8,1.8 3.2,1.8l30.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L48.0,10.0C48.0,7.8 46.2,6.0 44.0,6.0zM38.0,31.2L35.2,34.0L28.0,26.8L20.8,34.0L18.0,31.2l7.2,-7.2L18.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L30.8,24.0L38.0,31.2z"/>
-</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
new file mode 100644
index 0000000..6edae4b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M22,3H7C6.31,3 5.77,3.35 5.41,3.88l-5.04,7.57c-0.22,0.34 -0.22,0.77 0,1.11l5.04,7.56C5.77,20.64 6.31,21 7,21h15c1.1,0 2,-0.9 2,-2V5C24,3.9 23.1,3 22,3zM18.3,16.3L18.3,16.3c-0.39,0.39 -1.02,0.39 -1.41,0L14,13.41l-2.89,2.89c-0.39,0.39 -1.02,0.39 -1.41,0h0c-0.39,-0.39 -0.39,-1.02 0,-1.41L12.59,12L9.7,9.11c-0.39,-0.39 -0.39,-1.02 0,-1.41l0,0c0.39,-0.39 1.02,-0.39 1.41,0L14,10.59l2.89,-2.89c0.39,-0.39 1.02,-0.39 1.41,0v0c0.39,0.39 0.39,1.02 0,1.41L15.41,12l2.89,2.89C18.68,15.27 18.68,15.91 18.3,16.3z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
new file mode 100644
index 0000000..5026f07
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9,16.2l-3.5,-3.5a0.984,0.984 0,0 0,-1.4 0,0.984 0.984,0 0,0 0,1.4l4.19,4.19c0.39,0.39 1.02,0.39 1.41,0L20.3,7.7a0.984,0.984 0,0 0,0 -1.4,0.984 0.984,0 0,0 -1.4,0L9,16.2z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 3283e04..631cc0d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -62,7 +62,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:src="@drawable/ic_backspace_24dp"
+ android:src="@drawable/ic_backspace_black_24dp"
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
@@ -73,6 +73,7 @@
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
android:tint="@color/pin_delete_color"
+ android:tintMode="src_in"
/>
<View
android:id="@+id/divider"
@@ -204,7 +205,7 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingBottom="11sp"
- android:src="@drawable/ic_done_wht"
+ android:src="@drawable/ic_done_black_24dp"
style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index cf87f90..97c8965 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -75,7 +75,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:src="@drawable/ic_backspace_24dp"
+ android:src="@drawable/ic_backspace_black_24dp"
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
@@ -86,6 +86,7 @@
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
android:tint="@color/pin_delete_color"
+ android:tintMode="src_in"
/>
<View
android:id="@+id/divider"
@@ -213,7 +214,7 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingBottom="11sp"
- android:src="@drawable/ic_done_wht"
+ android:src="@drawable/ic_done_black_24dp"
style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index 3cae493..d4c5d74 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -76,7 +76,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:src="@drawable/ic_backspace_24dp"
+ android:src="@drawable/ic_backspace_black_24dp"
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
@@ -87,6 +87,7 @@
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
android:tint="@color/pin_delete_color"
+ android:tintMode="src_in"
/>
<View
android:id="@+id/divider"
@@ -214,7 +215,7 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingBottom="11sp"
- android:src="@drawable/ic_done_wht"
+ android:src="@drawable/ic_done_black_24dp"
style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
new file mode 100644
index 0000000..2ae7212
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="3171996292755059205">"Keyguard"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"Type PIN code"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"Type SIM PUK and new PIN code"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"SIM PUK code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"New SIM PIN code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482">""<font size="17">"Touch to type password"</font>""</string>
+ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Type password to unlock"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Type PIN to unlock"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
+ <string name="keyguard_plugged_in" msgid="89308975354638682">"Charging"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charging rapidly"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"Charging slowly"</string>
+ <string name="keyguard_low_battery" msgid="9218432555787624490">"Connect your charger."</string>
+ <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"Press Menu to unlock."</string>
+ <string name="keyguard_network_locked_message" msgid="6743537524631420759">"Network locked"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"No SIM card"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"No SIM card in tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"No SIM card in phone."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"Insert a SIM card."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"The SIM card is missing or not readable. Insert a SIM card."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"Unusable SIM card."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+ <string name="keyguard_sim_locked_message" msgid="953766009432168127">"SIM card is locked."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"SIM card is PUK-locked."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"Unlocking SIM card…"</string>
+ <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"PIN area"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM PIN area"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
+ <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
+ <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+ <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
+ <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgot Pattern"</string>
+ <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
+ <string name="kg_wrong_password" msgid="4580683060277329277">"Wrong Password"</string>
+ <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+ <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
+ <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+ <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
+ <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
+ <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"Enter desired PIN code"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"Confirm desired PIN code"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"Unlocking SIM card…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"Type a PIN that is 4 to 8 numbers."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"PUK code should be 8 numbers or more."</string>
+ <string name="kg_invalid_puk" msgid="5399287873762592502">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"PIN codes does not match"</string>
+ <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"Too many pattern attempts"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This tablet will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="2365964340830006961">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This phone will be reset, which will delete all its data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="1365418870560228936">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="2151286957817486128">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, this user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="5464020754932560928">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="6171564974118059">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. This user will be removed, which will delete all user data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"Incorrect SIM PIN code you must now contact your carrier to unlock your device."</string>
+ <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
+ <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
+ <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
+ </plurals>
+ <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"SIM is unusable. Contact your carrier."</string>
+ <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
+ <item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
+ <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
+ </plurals>
+ <string name="kg_password_pin_failed" msgid="8769990811451236223">"SIM PIN operation failed!"</string>
+ <string name="kg_password_puk_failed" msgid="1331621440873439974">"SIM PUK operation failed!"</string>
+ <string name="kg_pin_accepted" msgid="7637293533973802143">"Code Accepted!"</string>
+ <string name="keyguard_carrier_default" msgid="4274828292998453695">"No service."</string>
+ <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Switch input method"</string>
+ <string name="airplane_mode" msgid="3807209033737676010">"Airplane mode"</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Pattern required after device restarts"</string>
+ <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"PIN required after device restarts"</string>
+ <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Password required after device restarts"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"Pattern required for additional security"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"PIN required for additional security"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"Password required for additional security"</string>
+ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Pattern required when you switch profiles"</string>
+ <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"PIN required when you switch profiles"</string>
+ <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Password required when you switch profiles"</string>
+ <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Device locked by admin"</string>
+ <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Device was locked manually"</string>
+ <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
+ <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm pattern.</item>
+ <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm pattern.</item>
+ </plurals>
+ <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
+ <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm PIN.</item>
+ <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm PIN.</item>
+ </plurals>
+ <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
+ <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm password.</item>
+ <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm password.</item>
+ </plurals>
+ <string name="fingerprint_not_recognized" msgid="348813995267914625">"Not recognized"</string>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index c108d1e..ecd27de 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -110,9 +110,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"端末の再起動後はパターンの入力が必要となります"</string>
<string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"端末の再起動後は PIN の入力が必要となります"</string>
<string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"端末の再起動後はパスワードの入力が必要となります"</string>
- <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"セキュリティを強化するにはパターンが必要です"</string>
- <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"セキュリティを強化するには PIN が必要です"</string>
- <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"セキュリティを強化するにはパスワードが必要です"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"追加の確認のためパターンが必要です"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"追加の確認のため PIN が必要です"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"追加の確認のためパスワードが必要です"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"プロファイルを切り替えるにはパターンが必要です"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"プロファイルを切り替えるには PIN が必要です"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"プロファイルを切り替えるにはパスワードが必要です"</string>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 4f82147..826e3ea 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -74,6 +74,8 @@
</style>
<style name="keyguard_presentation_theme" parent="@android:style/Theme.Material.NoActionBar.Fullscreen">
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
index acc8531..6821e62 100644
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
@@ -45,7 +45,7 @@
android:duration="16"
android:propertyName="fillAlpha"
android:valueFrom="0.0"
- android:valueTo="1.0"
+ android:valueTo="0.5"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
index fac1ece..a8251dc 100644
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
@@ -45,7 +45,7 @@
android:duration="16"
android:propertyName="fillAlpha"
android:valueFrom="0.0"
- android:valueTo="1.0"
+ android:valueTo="0.5"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml
new file mode 100644
index 0000000..d6054c4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.8"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml
new file mode 100644
index 0000000..282170c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_2" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml
new file mode 100644
index 0000000..b59c664
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="116"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml
new file mode 100644
index 0000000..60d2396
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 0.0,0.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_1" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml
new file mode 100644
index 0000000..ef442e9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml
new file mode 100644
index 0000000..97782be
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="233"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 0.0,0.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml
new file mode 100644
index 0000000..d6054c4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.8"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml
new file mode 100644
index 0000000..573205ffd
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml
new file mode 100644
index 0000000..4b038b9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.54"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml
new file mode 100644
index 0000000..562985a8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.15667"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleX"
+ android:valueFrom="1.15667"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.15667"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleY"
+ android:valueFrom="1.15667"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
new file mode 100644
index 0000000..6c7e751
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
new file mode 100644
index 0000000..c699fe2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
new file mode 100644
index 0000000..5595e5c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml
new file mode 100644
index 0000000..4614bfc
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.8"
+ android:valueTo="1.8"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleX"
+ android:valueFrom="1.8"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml
new file mode 100644
index 0000000..f5cfcf9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_1" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml
new file mode 100644
index 0000000..0b74b3a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml
new file mode 100644
index 0000000..ba10224
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="216"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 0.0,25.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_2" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml
new file mode 100644
index 0000000..395bbf4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="199"
+ android:propertyName="pathData"
+ android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml
new file mode 100644
index 0000000..0115759
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="300"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 0.0,-25.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml
new file mode 100644
index 0000000..4614bfc
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.8"
+ android:valueTo="1.8"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleX"
+ android:valueFrom="1.8"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml
new file mode 100644
index 0000000..6b182be
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml
new file mode 100644
index 0000000..828f7a2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="alpha"
+ android:valueFrom="0.54"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml
new file mode 100644
index 0000000..89ab580
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="66"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.15667"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.15667"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="66"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.15667"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.15667"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
index 138c06a..547f42e 100644
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
@@ -37,14 +37,14 @@
<objectAnimator
android:duration="183"
android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="1.0"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
<objectAnimator
android:duration="16"
android:propertyName="fillAlpha"
- android:valueFrom="1.0"
+ android:valueFrom="0.5"
android:valueTo="0.0"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
index c4d38e0..e5fe4d1 100644
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
@@ -37,14 +37,14 @@
<objectAnimator
android:duration="183"
android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="1.0"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
<objectAnimator
android:duration="16"
android:propertyName="fillAlpha"
- android:valueFrom="1.0"
+ android:valueFrom="0.5"
android:valueTo="0.0"
android:valueType="floatType"
android:interpolator="@android:interpolator/linear" />
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate.xml b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
index 8bfe5f4..bc196c9 100755
--- a/packages/SystemUI/res/drawable/error_to_trustedstate.xml
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
@@ -17,9 +17,9 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="error_to_trustedstate"
- android:width="32dp"
+ android:width="24dp"
android:viewportWidth="24"
- android:height="32dp"
+ android:height="24dp"
android:viewportHeight="24" >
<group
android:name="lock"
@@ -30,7 +30,8 @@
android:translateY="2.9375" >
<path
android:name="ellipse_path_1"
- android:fillColor="#FFFFFFFF"
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5"
android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
</group>
<group
@@ -38,16 +39,16 @@
<path
android:name="path_1"
android:pathData="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="0" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
<group
android:name="lock_left_side" >
<path
android:name="path_2"
android:pathData="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="0" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
<group
android:name="lock_top"
@@ -56,7 +57,8 @@
<path
android:name="path_3"
android:pathData="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
- android:fillColor="#FFFFFFFF" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
</group>
<group
@@ -68,7 +70,7 @@
android:translateY="4" >
<path
android:name="bottompath"
- android:fillColor="#FFFFFFFF"
+ android:fillColor="?android:attr/colorError"
android:pathData="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z" />
</group>
</group>
@@ -81,7 +83,7 @@
android:translateY="-2" >
<path
android:name="toppath"
- android:fillColor="#FFFFFFFF"
+ android:fillColor="?android:attr/colorError"
android:pathData="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
</group>
</group>
@@ -94,7 +96,7 @@
android:name="circle" >
<path
android:name="circlepath"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?android:attr/colorError"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
diff --git a/packages/SystemUI/res/drawable/ic_close_white_rounded.xml b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
new file mode 100644
index 0000000..ca37698
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18.3,5.71a0.996,0.996 0,0 0,-1.41 0L12,10.59 7.11,5.7A0.996,0.996 0,1 0,5.7 7.11L10.59,12 5.7,16.89a0.996,0.996 0,1 0,1.41 1.41L12,13.41l4.89,4.89a0.996,0.996 0,1 0,1.41 -1.41L13.41,12l4.89,-4.89c0.38,-0.38 0.38,-1.02 0,-1.4z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_fingerprint.xml b/packages/SystemUI/res/drawable/ic_fingerprint.xml
index ee2cf03..7bbd39d 100644
--- a/packages/SystemUI/res/drawable/ic_fingerprint.xml
+++ b/packages/SystemUI/res/drawable/ic_fingerprint.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2015 The Android Open Source Project
+ ~ 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.
@@ -13,24 +13,55 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="32.0"
- android:viewportHeight="32.0">
- <path
- android:fillColor="#80ffffff"
- android:pathData="M23.7,5.9c-0.1,0.0 -0.2,0.0 -0.3,-0.1C21.0,4.5 18.6,3.9 16.0,3.9c-2.5,0.0 -4.6,0.6 -6.9,1.9C8.8,6.0 8.3,5.9 8.1,5.5C7.9,5.2 8.0,4.7 8.4,4.5c2.5,-1.4 4.9,-2.1 7.7,-2.1c2.8,0.0 5.4,0.7 8.0,2.1c0.4,0.2 0.5,0.6 0.3,1.0C24.2,5.7 24.0,5.9 23.7,5.9z"/>
- <path
- android:fillColor="#80ffffff"
- android:pathData="M5.3,13.2c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,-0.2 -0.4,-0.7 -0.2,-1.0c1.3,-1.9 2.9,-3.4 4.9,-4.5c4.1,-2.2 9.3,-2.2 13.4,0.0c1.9,1.1 3.6,2.5 4.9,4.4c0.2,0.3 0.1,0.8 -0.2,1.0c-0.3,0.2 -0.8,0.1 -1.0,-0.2c-1.2,-1.7 -2.6,-3.0 -4.3,-4.0c-3.7,-2.0 -8.3,-2.0 -12.0,0.0c-1.7,0.9 -3.2,2.3 -4.3,4.0C5.7,13.1 5.5,13.2 5.3,13.2z"/>
- <path
- android:fillColor="#80ffffff"
- android:pathData="M13.3,29.6c-0.2,0.0 -0.4,-0.1 -0.5,-0.2c-1.1,-1.2 -1.7,-2.0 -2.6,-3.6c-0.9,-1.7 -1.4,-3.7 -1.4,-5.9c0.0,-4.1 3.3,-7.4 7.4,-7.4c4.1,0.0 7.4,3.3 7.4,7.4c0.0,0.4 -0.3,0.7 -0.7,0.7s-0.7,-0.3 -0.7,-0.7c0.0,-3.3 -2.7,-5.9 -5.9,-5.9c-3.3,0.0 -5.9,2.7 -5.9,5.9c0.0,2.0 0.4,3.8 1.2,5.2c0.8,1.6 1.4,2.2 2.4,3.3c0.3,0.3 0.3,0.8 0.0,1.0C13.7,29.5 13.5,29.6 13.3,29.6z"/>
- <path
- android:fillColor="#80ffffff"
- android:pathData="M22.6,27.1c-1.6,0.0 -2.9,-0.4 -4.1,-1.2c-1.9,-1.4 -3.1,-3.6 -3.1,-6.0c0.0,-0.4 0.3,-0.7 0.7,-0.7s0.7,0.3 0.7,0.7c0.0,1.9 0.9,3.7 2.5,4.8c0.9,0.6 1.9,1.0 3.2,1.0c0.3,0.0 0.8,0.0 1.3,-0.1c0.4,-0.1 0.8,0.2 0.8,0.6c0.1,0.4 -0.2,0.8 -0.6,0.8C23.4,27.1 22.8,27.1 22.6,27.1z"/>
- <path
- android:fillColor="#80ffffff"
- android:pathData="M20.0,29.9c-0.1,0.0 -0.1,0.0 -0.2,0.0c-2.1,-0.6 -3.4,-1.4 -4.8,-2.9c-1.8,-1.9 -2.8,-4.4 -2.8,-7.1c0.0,-2.2 1.8,-4.1 4.1,-4.1c2.2,0.0 4.1,1.8 4.1,4.1c0.0,1.4 1.2,2.6 2.6,2.6c1.4,0.0 2.6,-1.2 2.6,-2.6c0.0,-5.1 -4.2,-9.3 -9.3,-9.3c-3.6,0.0 -6.9,2.1 -8.4,5.4C7.3,17.1 7.0,18.4 7.0,19.8c0.0,1.1 0.1,2.7 0.9,4.9c0.1,0.4 -0.1,0.8 -0.4,0.9c-0.4,0.1 -0.8,-0.1 -0.9,-0.4c-0.6,-1.8 -0.9,-3.6 -0.9,-5.4c0.0,-1.6 0.3,-3.1 0.9,-4.4c1.7,-3.8 5.6,-6.3 9.8,-6.3c5.9,0.0 10.7,4.8 10.7,10.7c0.0,2.2 -1.8,4.1 -4.1,4.1s-4.0,-1.8 -4.0,-4.1c0.0,-1.4 -1.2,-2.6 -2.6,-2.6c-1.4,0.0 -2.6,1.2 -2.6,2.6c0.0,2.3 0.9,4.5 2.4,6.1c1.2,1.3 2.4,2.0 4.2,2.5c0.4,0.1 0.6,0.5 0.5,0.9C20.6,29.7 20.3,29.9 20.0,29.9z"/>
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:viewportWidth="24"
+ android:height="32dp"
+ android:viewportHeight="24" >
+ <group
+ android:translateX="12"
+ android:translateY="12.4"
+ android:scaleX="0.738"
+ android:scaleY="0.738" >
+ <group
+ android:translateX="33"
+ android:translateY="34" >
+ <path
+ android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ <path
+ android:name="ridge_7_path"
+ android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ <path
+ android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ <path
+ android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ <group
+ android:translateX="-97.5"
+ android:translateY="-142.5" >
+ <path
+ android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ </group>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
index 204af7e..bf0dc95 100644
--- a/packages/SystemUI/res/drawable/ic_lock_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -20,6 +20,6 @@
android:viewportHeight="24.0">
<path
- android:fillColor="@color/keyguard_affordance"
+ android:fillColor="?attr/wallpaperTextColor"
android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
index c877f06..232cf70 100644
--- a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -20,6 +20,6 @@
android:viewportHeight="24.0">
<path
- android:fillColor="@color/keyguard_affordance"
+ android:fillColor="?attr/wallpaperTextColor"
android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_minus.xml b/packages/SystemUI/res/drawable/ic_qs_minus.xml
index 6a3410a..ead6b03 100644
--- a/packages/SystemUI/res/drawable/ic_qs_minus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_minus.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ 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.
@@ -15,12 +15,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24.0dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24.0dp" >
-
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M38.0,26.0L10.0,26.0l0.0,-4.0l28.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+ android:pathData="M18,13H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h12c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_plus.xml b/packages/SystemUI/res/drawable/ic_qs_plus.xml
index 393f51c..f1b19e1e 100644
--- a/packages/SystemUI/res/drawable/ic_qs_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_plus.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ 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.
@@ -15,12 +15,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24.0dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24.0dp" >
-
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+ android:pathData="M18,13h-5v5c0,0.55 -0.45,1 -1,1h0c-0.55,0 -1,-0.45 -1,-1v-5H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h5V6c0,-0.55 0.45,-1 1,-1h0c0.55,0 1,0.45 1,1v5h5c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
index 1feb49c..96d8484 100644
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
@@ -1,63 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:name="root"
- android:alpha="1.0"
- android:height="42dp"
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_signal_workmode_disable"
android:width="42dp"
- android:viewportHeight="42"
- android:viewportWidth="42" >
+ android:viewportWidth="42"
+ android:height="42dp"
+ android:viewportHeight="42" >
<group
- android:name="ic_signal_briefcase"
- android:translateX="21.9995"
- android:translateY="25.73401" >
+ android:name="suitcase"
+ android:translateX="21"
+ android:translateY="36.9375"
+ android:scaleX="0.1"
+ android:scaleY="0.1" >
<group
- android:name="ic_signal_briefcase_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
+ android:name="suitcase_pivot"
+ android:translateY="-158" >
<clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ android:name="mask_1"
+ android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" />
<group
- android:name="cross" >
+ android:name="whole"
+ android:translateX="-1.11523"
+ android:translateY="32.0918" >
<path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:name="rectangle_path_1"
android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
+ android:strokeWidth="65"
+ android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" />
</group>
<group
- android:name="briefcase"
- android:translateX="23.481"
- android:translateY="18.71151" >
+ android:name="handle"
+ android:translateY="-100" >
<path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" />
+ android:name="rectangle_path_2"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeWidth="35"
+ android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" />
+ </group>
+ <group
+ android:name="case"
+ android:translateY="32.68518" >
+ <group
+ android:name="case_pivot"
+ android:translateY="-32.68518" >
+ <group
+ android:name="bottom"
+ android:translateY="-97.62964" >
+ <group
+ android:name="bottom_pivot"
+ android:translateY="40" >
+ <group
+ android:name="rectangle_path_3_position" >
+ <path
+ android:name="rectangle_path_3"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="top"
+ android:translateY="163" >
+ <group
+ android:name="top_pivot"
+ android:translateY="-40" >
+ <group
+ android:name="rectangle_path_4_position" >
+ <path
+ android:name="rectangle_path_4"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="left"
+ android:translateX="-175.00635"
+ android:translateY="30" >
+ <group
+ android:name="left_pivot"
+ android:translateX="50.00635" >
+ <path
+ android:name="rectangle_path_5"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+ <group
+ android:name="right"
+ android:translateX="174.97778"
+ android:translateY="30" >
+ <group
+ android:name="right_pivot"
+ android:translateX="-49.97778" >
+ <path
+ android:name="rectangle_path_6"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="stick"
+ android:translateX="-166.59082"
+ android:translateY="-156.51367"
+ android:scaleY="0"
+ android:rotation="-45" >
+ <group
+ android:name="stick_pivot"
+ android:translateX="0.18161"
+ android:translateY="243.8158" >
+ <path
+ android:name="stickito"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
</group>
</group>
</group>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
new file mode 100644
index 0000000..4a2bd54
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_workmode_disable" >
+ <target
+ android:name="mask_1"
+ android:animation="@anim/ic_signal_workmode_disable_mask_1_animation" />
+ <target
+ android:name="whole"
+ android:animation="@anim/ic_signal_workmode_disable_whole_animation" />
+ <target
+ android:name="rectangle_path_3_position"
+ android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_position_animation" />
+ <target
+ android:name="rectangle_path_3"
+ android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_animation" />
+ <target
+ android:name="rectangle_path_4_position"
+ android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_position_animation" />
+ <target
+ android:name="rectangle_path_4"
+ android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_animation" />
+ <target
+ android:name="left"
+ android:animation="@anim/ic_signal_workmode_disable_left_animation" />
+ <target
+ android:name="right"
+ android:animation="@anim/ic_signal_workmode_disable_right_animation" />
+ <target
+ android:name="stick"
+ android:animation="@anim/ic_signal_workmode_disable_stick_animation" />
+ <target
+ android:name="ic_signal_workmode_disable"
+ android:animation="@anim/ic_signal_workmode_disable_stickito_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml
index f962594..2d4f0b5 100644
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml
@@ -1,62 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:name="root"
- android:height="42dp"
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_signal_workmode_enable"
android:width="42dp"
- android:viewportHeight="42"
- android:viewportWidth="42" >
+ android:viewportWidth="42"
+ android:height="42dp"
+ android:viewportHeight="42" >
<group
- android:name="ic_signal_briefcase"
- android:translateX="21.9995"
- android:translateY="25.73401" >
+ android:name="suitcase"
+ android:translateX="21"
+ android:translateY="36.9375"
+ android:scaleX="0.1"
+ android:scaleY="0.1" >
<group
- android:name="ic_signal_briefcase_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
+ android:name="suitcase_pivot"
+ android:translateY="-158" >
<clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ android:name="mask_1"
+ android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" />
<group
- android:name="cross" >
+ android:name="whole"
+ android:translateX="-1.11523"
+ android:translateY="32.0918"
+ android:scaleX="0"
+ android:scaleY="0" >
<path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:name="rectangle_path_1"
android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
+ android:strokeWidth="65"
+ android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" />
</group>
<group
- android:name="briefcase"
- android:translateX="23.481"
- android:translateY="18.71151" >
+ android:name="handle"
+ android:translateY="-100" >
<path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1"
- android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" />
+ android:name="rectangle_path_2"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeWidth="35"
+ android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" />
+ </group>
+ <group
+ android:name="case"
+ android:translateY="32.68518" >
+ <group
+ android:name="case_pivot"
+ android:translateY="-32.68518" >
+ <group
+ android:name="bottom"
+ android:translateY="-97.62964" >
+ <group
+ android:name="bottom_pivot"
+ android:translateY="40" >
+ <group
+ android:name="rectangle_path_3_position"
+ android:translateY="25" >
+ <path
+ android:name="rectangle_path_3"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="top"
+ android:translateY="163" >
+ <group
+ android:name="top_pivot"
+ android:translateY="-40" >
+ <group
+ android:name="rectangle_path_4_position"
+ android:translateY="-25" >
+ <path
+ android:name="rectangle_path_4"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="left"
+ android:translateX="-175.00635"
+ android:translateY="30"
+ android:scaleX="1.8" >
+ <group
+ android:name="left_pivot"
+ android:translateX="50.00635" >
+ <path
+ android:name="rectangle_path_5"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+ <group
+ android:name="right"
+ android:translateX="174.97778"
+ android:translateY="30"
+ android:scaleX="1.8" >
+ <group
+ android:name="right_pivot"
+ android:translateX="-49.97778" >
+ <path
+ android:name="rectangle_path_6"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="stick"
+ android:translateX="-166.59082"
+ android:translateY="-156.51367"
+ android:rotation="-45" >
+ <group
+ android:name="stick_pivot"
+ android:translateX="0.18161"
+ android:translateY="243.8158" >
+ <path
+ android:name="stickito"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1"
+ android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
</group>
</group>
</group>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
new file mode 100644
index 0000000..c98f800
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_workmode_enable" >
+ <target
+ android:name="mask_1"
+ android:animation="@anim/ic_signal_workmode_enable_mask_1_animation" />
+ <target
+ android:name="whole"
+ android:animation="@anim/ic_signal_workmode_enable_whole_animation" />
+ <target
+ android:name="rectangle_path_3_position"
+ android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_position_animation" />
+ <target
+ android:name="rectangle_path_3"
+ android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_animation" />
+ <target
+ android:name="rectangle_path_4_position"
+ android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_position_animation" />
+ <target
+ android:name="rectangle_path_4"
+ android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_animation" />
+ <target
+ android:name="left"
+ android:animation="@anim/ic_signal_workmode_enable_left_animation" />
+ <target
+ android:name="right"
+ android:animation="@anim/ic_signal_workmode_enable_right_animation" />
+ <target
+ android:name="stick"
+ android:animation="@anim/ic_signal_workmode_enable_stick_animation" />
+ <target
+ android:name="ic_signal_workmode_enable"
+ android:animation="@anim/ic_signal_workmode_enable_stickito_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
index 81da26d..8d382a3 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2015 The Android Open Source Project
+ ~ 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.
@@ -34,7 +34,7 @@
<path
android:name="ridge_5_path"
android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -44,7 +44,7 @@
<path
android:name="ridge_7_path"
android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -54,7 +54,7 @@
<path
android:name="ridge_6_path"
android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -64,7 +64,7 @@
<path
android:name="ridge_2_path"
android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -76,7 +76,7 @@
<path
android:name="ridge_1_path"
android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
index 8b517b6..4fe160d 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2015 The Android Open Source Project
+ ~ 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.
@@ -34,7 +34,7 @@
<path
android:name="ridge_5_path"
android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
@@ -45,7 +45,7 @@
<path
android:name="ridge_7_path"
android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
@@ -56,7 +56,7 @@
<path
android:name="ridge_6_path"
android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
@@ -67,7 +67,7 @@
<path
android:name="ridge_2_path"
android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
@@ -80,7 +80,7 @@
<path
android:name="ridge_1_path"
android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
index f2eca8c..832716a 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
@@ -37,7 +37,8 @@
<path
android:name="ridge_5_path"
android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
android:trimPathEnd="0" />
@@ -47,7 +48,8 @@
<path
android:name="ridge_7_path"
android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
android:trimPathEnd="0" />
@@ -57,7 +59,8 @@
<path
android:name="ridge_6_path"
android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
android:trimPathStart="1" />
@@ -67,7 +70,8 @@
<path
android:name="ridge_2_path"
android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
android:trimPathStart="1" />
@@ -79,7 +83,8 @@
<path
android:name="ridge_1_path"
android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
+ android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round"
android:trimPathEnd="0" />
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
index 218dd06..7cc2e5c 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
@@ -36,7 +36,7 @@
<path
android:name="ridge_5_path"
android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -46,7 +46,7 @@
<path
android:name="ridge_7_path"
android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -56,7 +56,7 @@
<path
android:name="ridge_6_path"
android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -66,7 +66,7 @@
<path
android:name="ridge_2_path"
android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
@@ -78,7 +78,7 @@
<path
android:name="ridge_1_path"
android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?attr/wallpaperTextColor"
android:strokeAlpha="0.5"
android:strokeWidth="1.45"
android:strokeLineCap="round" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml
deleted file mode 100644
index 1e41a31..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="27.0dp"
- android:height="22.0dp"
- android:viewportWidth="27.0"
- android:viewportHeight="22.0">
- <clip-path
- android:name="mask"
- android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="work_badge"
- android:translateX="3.0"
- android:scaleX="1.4"
- android:scaleY="1.4">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
- <path
- android:fillColor="@android:color/white"
- android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml
deleted file mode 100644
index d67c89ac..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="27.0dp"
- android:height="22.0dp"
- android:alpha="1.0"
- android:viewportWidth="27.0"
- android:viewportHeight="22.0">
- <group
- android:name="work_badge"
- android:translateX="3.0"
- android:scaleX="1.4"
- android:scaleY="1.4">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
- <path
- android:fillColor="@android:color/white"
- android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
index 370f89c..e38b482 100644
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -1,42 +1,12 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="23dp"
- android:height="18dp"
- android:viewportWidth="23"
- android:viewportHeight="18">
-<!--
- The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
--->
+ android:width="23dp"
+ android:height="18dp"
+ android:viewportWidth="23.0"
+ android:viewportHeight="18.0">
+ <!--
+ The asset contains a briefcase symbol of 14.551dp x 13.824dp in the center.
+ -->
<path
- android:fillColor="@android:color/white"
- android:pathData="M15.0815,4.5903 L15.0815,3.43636 L13.9276,2.2 L9.14696,2.2 L7.99302,3.43636
-L7.99302,4.5903 L9.14696,4.5903 L9.14696,3.43636 L13.9276,3.43636
-L13.9276,4.5903 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M18.0488,4.5903 L5.02575,4.5903 C4.36635,4.5903,3.87181,5.08485,3.87181,5.74424
-L3.87181,9.28848 C3.87181,9.94788,4.36635,10.4424,5.02575,10.4424
-L9.72393,10.4424 L9.72393,9.28848 L13.2682,9.28848 L13.2682,10.4424
-L17.9664,10.4424 C18.6257,10.4424,19.1203,9.94788,19.1203,9.28848
-L19.1203,5.74424 C19.2027,5.08485,18.6257,4.5903,18.0488,4.5903 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.80635,12.8327 L9.80635,11.6788 L4.44878,11.6788 L4.44878,14.6461
-C4.44878,15.3055,4.94332,15.8,5.60272,15.8 L17.3894,15.8
-C18.0488,15.8,18.5433,15.3055,18.5433,14.6461 L18.5433,11.6788 L13.2682,11.6788
-L13.2682,12.8327 L9.80635,12.8327 Z" />
+ android:pathData="M17.32,5.06h-2.91V3.6c0,-0.81 -0.65,-1.46 -1.46,-1.46h-2.91c-0.81,0 -1.46,0.65 -1.46,1.46v1.46H5.68c-0.81,0 -1.45,0.65 -1.45,1.46l-0.01,8c0,0.81 0.65,1.46 1.46,1.46h11.64c0.81,0 1.46,-0.65 1.46,-1.46v-8C18.78,5.7 18.13,5.06 17.32,5.06zM11.5,11.6c-0.8,0 -1.46,-0.65 -1.46,-1.46c0,-0.8 0.65,-1.46 1.46,-1.46s1.46,0.65 1.46,1.46C12.96,10.95 12.3,11.6 11.5,11.6zM12.96,5.06h-2.91V3.6h2.91V5.06z"
+ android:fillColor="#FF000000"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml
index 35602b6..1dedd5d 100644
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2015 The Android Open Source Project
+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.
@@ -14,40 +14,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="23dp"
- android:height="18dp"
- android:viewportWidth="23"
- android:viewportHeight="18">
-<!--
- The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
--->
- <path
- android:pathData="M0,-6 L24,-6 L24,18 L0,18 L0,-6 Z" />
+ android:width="23dp"
+ android:height="18dp"
+ android:viewportWidth="23.0"
+ android:viewportHeight="18.0">
<path
android:fillColor="@android:color/white"
- android:pathData="M13.9892,11.6542 L13.4088,11.6542 L13.4088,12.8152 L9.843,12.8152 L9.843,11.6542
-L4.4529,11.6542 L4.4529,14.6395 C4.4529,15.3029,4.95045,15.8005,5.61384,15.8005
-L17.4721,15.8005 C17.6379,15.8005,17.8038,15.8005,17.9696,15.7175
-L13.9892,11.6542 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M18.7159,13.8932 L18.7159,11.6542 L16.477,11.6542
-C17.3062,12.4835,18.1355,13.3127,18.7159,13.8932 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6.85771,4.52272 L5.03337,4.52272
-C4.36998,4.52272,3.87243,5.02027,3.87243,5.68366 L3.87243,9.24942
-C3.87243,9.91282,4.36998,10.4104,5.03337,10.4104 L9.76008,10.4104
-L9.76008,9.24942 L11.5844,9.24942 L6.85771,4.52272 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.1796,4.35687 L9.1796,3.36177 L13.9063,3.36177 L13.9063,4.52272
-L9.34545,4.52272 C11.1698,6.34706,13.3258,8.5031,15.2331,10.4104
-L18.0525,10.4104 C18.7159,10.4104,19.2135,9.91282,19.2135,9.24942
-L19.2135,5.68366 C19.2135,5.02027,18.7159,4.52272,18.0525,4.52272
-L15.0673,4.52272 L15.0673,3.36177 L13.9063,2.20083 L9.1796,2.20083
-L8.10158,3.27885 C8.43328,3.61055,8.84791,4.02517,9.1796,4.35687 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M3.281,3.42136 L4.51236,2.19 L18.585,16.2626 L17.3536,17.494 L3.281,3.42136 Z" />
-</vector>
\ No newline at end of file
+ android:pathData="M19.4,16.6l-1.1,-1.1L8,5L5.1,2.2L4.2,3.1l2,2H5.7c-0.8,0 -1.4,0.6 -1.4,1.4v8c0,0.8 0.6,1.4 1.4,1.4h11.4l1.5,1.5L19.4,16.6zM18.7,6.5c0,-0.8 -0.6,-1.4 -1.4,-1.4h-2.9V3.6c0,-0.8 -0.6,-1.4 -1.4,-1.4h-3C9.2,2.1 8.6,2.8 8.6,3.6v0.2L18.7,14C18.7,14 18.7,6.5 18.7,6.5zM12.9,5.1H10V3.6h2.9V5.1z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error.xml b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
index 260940f..4a8e452 100755
--- a/packages/SystemUI/res/drawable/trusted_state_to_error.xml
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
@@ -17,9 +17,9 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="trusted_state_to_error"
- android:width="32dp"
+ android:width="24dp"
android:viewportWidth="24"
- android:height="32dp"
+ android:height="24dp"
android:viewportHeight="24" >
<group
android:name="lock"
@@ -30,7 +30,8 @@
android:translateY="2.9375" >
<path
android:name="ellipse_path_1"
- android:fillColor="#FFFFFFFF"
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5"
android:pathData="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z" />
</group>
<group
@@ -38,21 +39,24 @@
<path
android:name="path_1"
android:pathData="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
- android:fillColor="#FFFFFFFF" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
<group
android:name="lock_left_side" >
<path
android:name="path_2"
android:pathData="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
- android:fillColor="#FFFFFFFF" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
<group
android:name="lock_top" >
<path
android:name="path_3"
android:pathData="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
- android:fillColor="#FFFFFFFF" />
+ android:fillColor="?attr/wallpaperTextColor"
+ android:fillAlpha="0.5" />
</group>
</group>
<group
@@ -64,7 +68,7 @@
android:translateY="4" >
<path
android:name="bottompath"
- android:fillColor="#FFFFFFFF"
+ android:fillColor="?android:attr/colorError"
android:pathData="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
</group>
</group>
@@ -77,8 +81,7 @@
android:translateY="2.5" >
<path
android:name="toppath"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="0"
+ android:fillColor="?android:attr/colorError"
android:pathData="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z" />
</group>
</group>
@@ -91,7 +94,7 @@
android:name="circle" >
<path
android:name="circlepath"
- android:strokeColor="#FFFFFFFF"
+ android:strokeColor="?android:attr/colorError"
android:strokeWidth="2"
android:strokeLineCap="round"
android:trimPathStart="1"
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml
new file mode 100644
index 0000000..5009c6b
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.144628099174,0.0 l 0.855371900826,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml
new file mode 100644
index 0000000..678b90b
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.534759358289,0.0 l 0.465240641711,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml
new file mode 100644
index 0000000..6c6df60
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.313385868073,0.330828523695 0.125984191895,0.661170632677 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml
new file mode 100644
index 0000000..b1eec483
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.0 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml
new file mode 100644
index 0000000..17ff65a
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml
new file mode 100644
index 0000000..aee48dc
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.66666667,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..66cfaff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml
new file mode 100644
index 0000000..4a5fde9
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml
new file mode 100644
index 0000000..0f35e5d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.714960628748,0.0 0.678740215302,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml
new file mode 100644
index 0000000..626f9ef
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.392038600724,0.0 l 0.607961399276,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml
new file mode 100644
index 0000000..17ff65a
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml
new file mode 100644
index 0000000..96bdb48
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.337078651685,0.0 l 0.662921348315,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml
new file mode 100644
index 0000000..a91610d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.66666667,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..a0118d70
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..1820bab
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index ddd8ef8..2fd4df4 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -88,8 +88,7 @@
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:contentDescription="@string/accessibility_unlock_button"
- android:scaleType="center"
- android:tint="?attr/wallpaperTextColor" />
+ android:scaleType="center" />
<FrameLayout
android:id="@+id/overlay_container"
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index a621c7c..53f5dfe 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -24,7 +24,7 @@
android:paddingStart="8dp"
android:paddingEnd="8dp">
- <FrameLayout
+ <com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -44,7 +44,7 @@
android:orientation="horizontal"
android:clipChildren="false" />
- </FrameLayout>
+ </com.android.systemui.statusbar.phone.NearestTouchFrame>
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index bf48c7f..39cdff4 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -24,7 +24,7 @@
android:paddingTop="8dp"
android:paddingBottom="8dp">
- <FrameLayout
+ <com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -44,7 +44,7 @@
android:orientation="vertical"
android:clipChildren="false" />
- </FrameLayout>
+ </com.android.systemui.statusbar.phone.NearestTouchFrame>
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 63f80ae..1fd239b 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -40,7 +40,6 @@
android:background="@color/qs_detail_progress_track"
android:src="@drawable/indeterminate_anim"
android:scaleType="fitXY"
- android:translationY="16dp"
/>
<com.android.systemui.qs.NonInterceptingScrollView
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index 38627b6..7ffcb1e 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -51,7 +51,7 @@
android:clickable="true"
android:contentDescription="@string/accessibility_desc_close"
android:scaleType="center"
- android:src="@drawable/ic_close_white" />
+ android:src="@drawable/ic_close_white_rounded" />
<TextView
android:id="@+id/zen_introduction_message"
diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index 2b4a0f5..ab52465 100644
--- a/packages/SystemUI/res/layout/zen_mode_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -27,6 +27,8 @@
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:gravity="center_vertical"
android:layout_centerVertical="true"
android:orientation="vertical"
android:layout_toEndOf="@android:id/checkbox"
@@ -79,4 +81,4 @@
android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_qs_plus" />
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 4261641..3826bdd 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -59,7 +59,7 @@
android:clickable="true"
android:contentDescription="@string/accessibility_desc_close"
android:scaleType="center"
- android:src="@drawable/ic_close_white" />
+ android:src="@drawable/ic_close_white_rounded" />
<TextView
android:id="@+id/zen_introduction_message"
@@ -93,7 +93,7 @@
</RelativeLayout>
- <LinearLayout
+ <com.android.systemui.volume.ZenRadioLayout
android:id="@+id/zen_conditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -111,7 +111,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
- </LinearLayout>
+ </com.android.systemui.volume.ZenRadioLayout>
<TextView
android:id="@+id/zen_alarm_warning"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 2533b50..30750ab 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervang"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Programme wat op die agtergrond loop"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik vir besonderhede oor battery- en datagebruik"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Skakel mobiele data af?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index f524201..42aa76c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ተካ"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"የተንቀሳቃሽ ስልክ ውሂብ ይጥፋ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index adb76b9..fff3a82 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -254,7 +254,7 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
- <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"و<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
<item quantity="zero"><xliff:g id="NUMBER_1">%s</xliff:g> إشعار آخر بداخل المجموعة.</item>
<item quantity="two">إشعاران (<xliff:g id="NUMBER_1">%s</xliff:g>) آخران بداخل المجموعة.</item>
@@ -797,4 +797,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"استبدال"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"التطبيقات التي تعمل في الخلفية"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"هل تريد إيقاف تشغيل بيانات الجوال؟"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a7b3b03..37167b6 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Əvəz edin"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Arxa fonda işləyən tətbiqlər"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil data söndürülsün?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6547f0f..5255aeb 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -779,4 +779,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije pokrenute u pozadini"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Želite da onemogućite mobilne podatke?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 6d6d1b2..48a1be2 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замяніць"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Праграмы, якія працуюць у фонавым рэжыме"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Выключыць мабільную перадачу даных?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 86e0278..8f0d893 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замяна"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работещи на заден план"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Да се изключат ли мобилните данни?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8db54c8..94f0deb 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"বদলে দিন"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"পটভূমিতে অ্যাপ চালু আছে"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"মোবাইল ডেটা বন্ধ করবেন?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 337b68f..6584f9c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -781,4 +781,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije koje rade u pozadini"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Želite li isključiti prijenos mobilnih podataka?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 5aa85b8..cb929d9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -726,8 +726,8 @@
<string name="pip_phone_minimize" msgid="1079119422589131792">"Minimitza"</string>
<string name="pip_phone_close" msgid="8416647892889710330">"Tanca"</string>
<string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Arrossega cap avall per ignorar-ho"</string>
- <string name="pip_menu_title" msgid="3328510504196964712">"Menú per a Imatge en imatge"</string>
- <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> està en imatge en imatge"</string>
+ <string name="pip_menu_title" msgid="3328510504196964712">"Menú per a Pantalla en pantalla"</string>
+ <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string>
<string name="pip_notification_message" msgid="5619512781514343311">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
<string name="pip_play" msgid="1417176722760265888">"Reprodueix"</string>
<string name="pip_pause" msgid="8881063404466476571">"Posa en pausa"</string>
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substitueix"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacions que s\'estan executant en segon pla"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vols desactivar les dades mòbils?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ed4bd0f..c882e7c 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradit"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikace běžící na pozadí"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vypnout mobilní data?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c7367be..4edc307 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstat"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps, der kører i baggrunden"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryk for at se oplysninger om batteri- og dataforbrug"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vil du deaktivere mobildata?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ed57564..3451ae8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -777,4 +777,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersetzen"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps, die im Hintergrund ausgeführt werden"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Für Details zur Akku- und Datennutzung tippen"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobile Daten deaktivieren?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c206d86..db351ea 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -51,8 +51,8 @@
<string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Ρύθμιση μεθόδων εισαγωγής"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Φυσικό πληκτρολόγιο"</string>
- <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
- <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτού του αξεσουάρ USB;"</string>
<string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Δεν έχετε εφαρμογή που να συνεργάζεται με το αξεσουάρ USB. Για περισσότερα: <xliff:g id="URL">%1$s</xliff:g>"</string>
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Αντικατάσταση"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Απενεργοποίηση δεδομένων κινητής τηλεφωνίας;"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index a9cd4dd..bfac5b7 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index a9cd4dd..bfac5b7 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index a9cd4dd..bfac5b7 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC-land/strings.xml b/packages/SystemUI/res/values-en-rXC-land/strings.xml
new file mode 100644
index 0000000..957164f
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Screen is now locked in landscape orientation."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/config.xml b/packages/SystemUI/res/values-en-rXC/config.xml
new file mode 100644
index 0000000..5309563
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..6a1583d
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -0,0 +1,777 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="7164937344850004466">"System UI"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Clear"</string>
+ <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remove from list"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App info"</string>
+ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Your recent screens appear here"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dismiss recent apps"</string>
+ <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
+ <item quantity="other">%d screens in Overview</item>
+ <item quantity="one">1 screen in Overview</item>
+ </plurals>
+ <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No notifications"</string>
+ <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Ongoing"</string>
+ <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
+ <string name="battery_low_title" msgid="6456385927409742437">"Battery is low"</string>
+ <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining"</string>
+ <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> remaining. Battery saver is on."</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported.\nUse only the supplied charger."</string>
+ <string name="invalid_charger_title" msgid="3515740382572798460">"USB charging not supported."</string>
+ <string name="invalid_charger_text" msgid="5474997287953892710">"Use only the supplied charger."</string>
+ <string name="battery_low_why" msgid="4553600287639198111">"Settings"</string>
+ <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Turn on battery saver?"</string>
+ <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Turn on"</string>
+ <string name="battery_saver_start_action" msgid="5576697451677486320">"Turn on battery saver"</string>
+ <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Settings"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Auto-rotate screen"</string>
+ <string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
+ <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
+ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string>
+ <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB accessory is connected?"</string>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"No installed apps work with this USB accessory. Learn more about this accessory at <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string>
+ <string name="label_view" msgid="6304565553218192990">"View"</string>
+ <string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string>
+ <string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string>
+ <string name="usb_debugging_title" msgid="4513918393387141949">"Allow USB debugging?"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"The computer\'s RSA key fingerprint is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_always" msgid="303335496705863070">"Always allow from this computer"</string>
+ <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB debugging not allowed"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, please switch to an Admin user."</string>
+ <string name="compat_mode_on" msgid="6623839244840638213">"Zoom to fill screen"</string>
+ <string name="compat_mode_off" msgid="4434467572461327898">"Stretch to fill screen"</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Saving screenshot…"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Saving screenshot…"</string>
+ <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot is being saved."</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
+ <string name="screenshot_saved_text" msgid="2685605830386712477">"Tap to view your screenshot."</string>
+ <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+ <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string>
+ <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string>
+ <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organization"</string>
+ <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
+ <string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
+ <string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"Install Android File Transfer app for Mac"</string>
+ <string name="accessibility_back" msgid="567011538994429120">"Back"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+ <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+ <string name="accessibility_accessibility_button" msgid="7601252764577607915">"Accessibility"</string>
+ <string name="accessibility_recent" msgid="5208608566793607626">"Overview"</string>
+ <string name="accessibility_search_light" msgid="1103867596330271848">"Search"</string>
+ <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
+ <string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string>
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
+ <string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string>
+ <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Waiting for fingerprint"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string>
+ <string name="unlock_label" msgid="8779712358041029439">"unlock"</string>
+ <string name="phone_label" msgid="2320074140205331708">"open phone"</string>
+ <string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string>
+ <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
+ <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
+ <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
+ <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
+ <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth disconnected."</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"No battery."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Battery one bar."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Battery two bars."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Battery three bars."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Battery full."</string>
+ <string name="accessibility_no_phone" msgid="4894708937052611281">"No phone."</string>
+ <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Phone one bar."</string>
+ <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Phone two bars."</string>
+ <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Phone three bars."</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Phone signal full."</string>
+ <string name="accessibility_no_data" msgid="4791966295096867555">"No data."</string>
+ <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data one bar."</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data two bars."</string>
+ <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data three bars."</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data signal full."</string>
+ <string name="accessibility_wifi_name" msgid="7202151365171148501">"Connected to <xliff:g id="WIFI">%s</xliff:g>."</string>
+ <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+ <string name="accessibility_cast_name" msgid="4026393061247081201">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"No WiMAX."</string>
+ <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX one bar."</string>
+ <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX two bars."</string>
+ <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX three bars."</string>
+ <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signal full."</string>
+ <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"Ethernet disconnected."</string>
+ <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"Ethernet connected."</string>
+ <string name="accessibility_no_signal" msgid="7064645320782585167">"No signal."</string>
+ <string name="accessibility_not_connected" msgid="6395326276213402883">"Not connected."</string>
+ <string name="accessibility_zero_bars" msgid="3806060224467027887">"Zero bars."</string>
+ <string name="accessibility_one_bar" msgid="1685730113192081895">"One bar."</string>
+ <string name="accessibility_two_bars" msgid="6437363648385206679">"Two bars."</string>
+ <string name="accessibility_three_bars" msgid="2648241415119396648">"Three bars."</string>
+ <string name="accessibility_signal_full" msgid="9122922886519676839">"Signal full."</string>
+ <string name="accessibility_desc_on" msgid="2385254693624345265">"On."</string>
+ <string name="accessibility_desc_off" msgid="6475508157786853157">"Off."</string>
+ <string name="accessibility_desc_connected" msgid="8366256693719499665">"Connected."</string>
+ <string name="accessibility_desc_connecting" msgid="3812924520316280149">"Connecting."</string>
+ <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+ <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+ <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+ <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+ <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+ <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+ <string name="accessibility_data_connection_4g_plus" msgid="3032226872470658661">"4G+"</string>
+ <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+ <string name="accessibility_data_connection_lte_plus" msgid="361876866906946007">"LTE+"</string>
+ <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+ <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string>
+ <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+ <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"No SIM."</string>
+ <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobile Data"</string>
+ <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobile Data On"</string>
+ <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobile Data Off"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Airplane mode."</string>
+ <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN on."</string>
+ <string name="accessibility_no_sims" msgid="3957997018324995781">"No SIM card."</string>
+ <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Carrier network changing."</string>
+ <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
+ <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"System settings."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
+ <string name="accessibility_overflow_action" msgid="5681882033274783311">"See all notifications"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Clear notification."</string>
+ <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS enabled."</string>
+ <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS acquiring."</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter enabled."</string>
+ <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringer vibrate."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
+ <!-- no translation found for accessibility_casting (6887382141726543668) -->
+ <skip />
+ <string name="accessibility_work_mode" msgid="2478631941714607225">"Work mode"</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Open <xliff:g id="APP">%s</xliff:g> application info."</string>
+ <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
+ <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
+ <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string>
+ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string>
+ <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Lock screen."</string>
+ <string name="accessibility_desc_settings" msgid="3417884241751434521">"Settings"</string>
+ <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Overview."</string>
+ <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"Work lock screen"</string>
+ <string name="accessibility_desc_close" msgid="7479755364962766729">"Close"</string>
+ <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi turned off."</string>
+ <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi turned on."</string>
+ <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Battery <xliff:g id="STATE">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Airplane mode off."</string>
+ <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Airplane mode on."</string>
+ <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Airplane mode turned off."</string>
+ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Airplane mode turned on."</string>
+ <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"Do not disturb on, priority only."</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Do not disturb on, total silence."</string>
+ <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"Do not disturb on, alarms only."</string>
+ <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Do not disturb."</string>
+ <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"Do not disturb off."</string>
+ <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Do not disturb turned off."</string>
+ <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Do not disturb turned on."</string>
+ <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string>
+ <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth off."</string>
+ <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth on."</string>
+ <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Bluetooth connecting."</string>
+ <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth connected."</string>
+ <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"Bluetooth turned off."</string>
+ <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"Bluetooth turned on."</string>
+ <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Location reporting off."</string>
+ <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Location reporting on."</string>
+ <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"Location reporting turned off."</string>
+ <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"Location reporting turned on."</string>
+ <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Close panel."</string>
+ <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"More time."</string>
+ <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"Less time."</string>
+ <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Flashlight off."</string>
+ <string name="accessibility_quick_settings_flashlight_unavailable" msgid="8012811023312280810">"Flashlight unavailable."</string>
+ <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Flashlight on."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Flashlight turned off."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Flashlight turned on."</string>
+ <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Color inversion turned off."</string>
+ <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Color inversion turned on."</string>
+ <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot turned off."</string>
+ <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot turned on."</string>
+ <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Screen casting stopped."</string>
+ <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Work mode off."</string>
+ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
+ <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
+ <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
+ <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string>
+ <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string>
+ <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
+ <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Charging"</string>
+ <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
+ <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobile data is paused"</string>
+ <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Data is paused"</string>
+ <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"The data limit you set has been reached. You are no longer using mobile data.\n\nIf you resume, charges may apply for data usage."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Resume"</string>
+ <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No Internet connection"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connected"</string>
+ <string name="gps_notification_searching_text" msgid="8574247005642736060">"Searching for GPS"</string>
+ <string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
+ <string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
+ <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
+ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> more notification inside.</item>
+ </plurals>
+ <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
+ <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
+ <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
+ <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
+ <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
+ <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Screen will now rotate automatically."</string>
+ <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Screen is now locked in landscape orientation."</string>
+ <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Screen is now locked in portrait orientation."</string>
+ <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
+ <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
+ <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+ <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
+ <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
+ <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarms only"</string>
+ <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Total silence"</string>
+ <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
+ <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> Devices)"</string>
+ <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Off"</string>
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"No paired devices available"</string>
+ <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brightness"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Auto-rotate"</string>
+ <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Auto-rotate screen"</string>
+ <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> mode"</string>
+ <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotation locked"</string>
+ <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Portrait"</string>
+ <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Landscape"</string>
+ <string name="quick_settings_ime_label" msgid="7073463064369468429">"Input Method"</string>
+ <string name="quick_settings_location_label" msgid="5011327048748762257">"Location"</string>
+ <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Location Off"</string>
+ <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media device"</string>
+ <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Emergency Calls Only"</string>
+ <string name="quick_settings_settings_label" msgid="5326556592578065401">"Settings"</string>
+ <string name="quick_settings_time_label" msgid="4635969182239736408">"Time"</string>
+ <string name="quick_settings_user_label" msgid="5238995632130897840">"Me"</string>
+ <string name="quick_settings_user_title" msgid="4467690427642392403">"User"</string>
+ <string name="quick_settings_user_new_user" msgid="9030521362023479778">"New user"</string>
+ <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+ <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Not Connected"</string>
+ <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No Network"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
+ <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi On"</string>
+ <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No Wi-Fi networks available"</string>
+ <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
+ <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
+ <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
+ <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+ <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
+ <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+ <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colors"</string>
+ <string name="quick_settings_color_space_label" msgid="853443689745584770">"Color correction mode"</string>
+ <string name="quick_settings_more_settings" msgid="326112621462813682">"More settings"</string>
+ <string name="quick_settings_done" msgid="3402999958839153376">"Done"</string>
+ <string name="quick_settings_connected" msgid="1722253542984847487">"Connected"</string>
+ <string name="quick_settings_connected_battery_level" msgid="4136051440381328892">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="quick_settings_connecting" msgid="47623027419264404">"Connecting..."</string>
+ <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
+ <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
+ <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
+ <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+ <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
+ <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
+ <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
+ <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Over limit"</string>
+ <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> used"</string>
+ <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
+ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string>
+ <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Work mode"</string>
+ <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Night Light"</string>
+ <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
+ <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
+ <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
+ <string name="recents_empty_message" msgid="808480104164008572">"No recent items"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"You\'ve cleared everything"</string>
+ <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
+ <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
+ <string name="recents_drag_hint_message" msgid="2649739267073203985">"Drag here to use split screen"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Custom"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Split screen to the top"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Split screen to the left"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Split screen to the right"</string>
+ <string-array name="recents_blacklist_array">
+ </string-array>
+ <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string>
+ <string name="expanded_header_battery_charging" msgid="205623198487189724">"Charging"</string>
+ <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> until full"</string>
+ <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Not charging"</string>
+ <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="zen_priority_introduction" msgid="1149025108714420281">"You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You\'ll still hear anything you choose to play including music, videos, and games."</string>
+ <string name="zen_alarms_introduction" msgid="4934328096749380201">"You won\'t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything you choose to play including music, videos, and games."</string>
+ <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customize"</string>
+ <string name="zen_silence_introduction_voice" msgid="3948778066295728085">"This blocks ALL sounds and vibrations, including from alarms, music, videos, and games. You\'ll still be able to make phone calls."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos, and games."</string>
+ <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
+ <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
+ <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
+ <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
+ <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organization"</string>
+ <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
+ <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Swipe from icon for voice assist"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Swipe from icon for camera"</string>
+ <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Total silence. This will also silence screen readers."</string>
+ <string name="interruption_level_none" msgid="6000083681244492992">"Total silence"</string>
+ <string name="interruption_level_priority" msgid="6426766465363855505">"Priority only"</string>
+ <string name="interruption_level_alarms" msgid="5226306993448328896">"Alarms only"</string>
+ <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nsilence"</string>
+ <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
+ <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
+ <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+ <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+ <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Show profile"</string>
+ <string name="user_add_user" msgid="5110251524486079492">"Add user"</string>
+ <string name="user_new_user_name" msgid="426540612051178753">"New user"</string>
+ <string name="guest_nickname" msgid="8059989128963789678">"Guest"</string>
+ <string name="guest_new_guest" msgid="600537543078847803">"Add guest"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"Remove guest"</string>
+ <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Remove guest?"</string>
+ <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"All apps and data in this session will be deleted."</string>
+ <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Remove"</string>
+ <string name="guest_wipe_session_title" msgid="6419439912885956132">"Welcome back, guest!"</string>
+ <string name="guest_wipe_session_message" msgid="8476238178270112811">"Do you want to continue your session?"</string>
+ <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Start over"</string>
+ <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Yes, continue"</string>
+ <string name="guest_notification_title" msgid="1585278533840603063">"Guest user"</string>
+ <string name="guest_notification_text" msgid="335747957734796689">"To delete apps and data, remove guest user"</string>
+ <string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVE GUEST"</string>
+ <string name="user_logout_notification_title" msgid="1453960926437240727">"Logout user"</string>
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Logout current user"</string>
+ <string name="user_logout_notification_action" msgid="1195428991423425062">"LOGOUT USER"</string>
+ <string name="user_add_user_title" msgid="4553596395824132638">"Add new user?"</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+ <string name="user_remove_user_title" msgid="4681256956076895559">"Remove user?"</string>
+ <string name="user_remove_user_message" msgid="1453218013959498039">"All apps and data of this user will be deleted."</string>
+ <string name="user_remove_user_remove" msgid="7479275741742178297">"Remove"</string>
+ <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
+ <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduces performance and background data"</string>
+ <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Turn off battery saver"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
+ <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
+ <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
+ <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
+ <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
+ <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
+ <string name="vpn_footer" msgid="2388611096129106812">"Network may be monitored"</string>
+ <string name="branded_vpn_footer" msgid="2168111859226496230">"Network may be monitored"</string>
+ <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Your organization manages this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> manages this device and may monitor network traffic"</string>
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Device is managed by your organization and connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Device is managed by your organization"</string>
+ <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Device is managed by your organization and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Your organization may monitor network traffic in your work profile"</string>
+ <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
+ <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Network may be monitored"</string>
+ <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Device connected to VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Work profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Personal profile connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Device connected to <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Device management"</string>
+ <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Profile monitoring"</string>
+ <string name="monitoring_title" msgid="169206259253048106">"Network monitoring"</string>
+ <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
+ <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Network logging"</string>
+ <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA certificates"</string>
+ <string name="disable_vpn" msgid="4435534311510272506">"Disable VPN"</string>
+ <string name="disconnect_vpn" msgid="1324915059568548655">"Disconnect VPN"</string>
+ <string name="monitoring_button_view_policies" msgid="100913612638514424">"View Policies"</string>
+ <string name="monitoring_description_named_management" msgid="5281789135578986303">"Your device is managed by <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_management" msgid="4573721970278370790">"Your device is managed by your organization.\n\nYour admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Your organization installed a certificate authority on this device. Your secure network traffic may be monitored or modified."</string>
+ <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Your organization installed a certificate authority in your work profile. Your secure network traffic may be monitored or modified."</string>
+ <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
+ <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Your admin has turned on network logging, which monitors traffic on your device."</string>
+ <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"You\'re connected to <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Your work profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Your personal profile is connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Your device is managed by <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
+ <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> uses <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> to manage your device."</string>
+ <string name="monitoring_description_do_body" msgid="3639594537660975895">"Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information."</string>
+ <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
+ <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"Learn more"</string>
+ <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
+ <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Open VPN Settings"</string>
+ <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+ <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Open trusted credentials"</string>
+ <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Your admin has turned on network logging, which monitors traffic on your device.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps, and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity."</string>
+ <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+ <string name="monitoring_description_app" msgid="1828472472674709532">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps, and websites."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps, and websites."</string>
+ <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps, and websites.\n\nFor more information, contact your admin."</string>
+ <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps, and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+ <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+ <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
+ <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
+ <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
+ <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
+ <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No thanks"</string>
+ <string name="hidden_notifications_setup" msgid="41079514801976810">"Set up"</string>
+ <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <string name="volume_zen_end_now" msgid="6930243045593601084">"Turn off now"</string>
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
+ <string name="screen_pinning_description" msgid="8909878447196419623">"This keeps it in view until you unpin. Touch & hold Back and Overview to unpin."</string>
+ <string name="screen_pinning_description_accessible" msgid="426190689254018656">"This keeps it in view until you unpin. Touch & hold Overview to unpin."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"No thanks"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
+ <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
+ <string name="stream_voice_call" msgid="4410002696470423714">"Call"</string>
+ <string name="stream_system" msgid="7493299064422163147">"System"</string>
+ <string name="stream_ring" msgid="8213049469184048338">"Ring"</string>
+ <string name="stream_music" msgid="9086982948697544342">"Media"</string>
+ <string name="stream_alarm" msgid="5209444229227197703">"Alarm"</string>
+ <string name="stream_notification" msgid="2563720670905665031">"Notification"</string>
+ <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">"Accessibility"</string>
+ <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap to unmute."</string>
+ <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
+ <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string>
+ <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string>
+ <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string>
+ <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volume controls shown. Swipe up to dismiss."</string>
+ <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volume controls hidden"</string>
+ <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
+ <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
+ <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string>
+ <string name="quick_settings" msgid="10042998191725428">"Quick Settings"</string>
+ <string name="status_bar" msgid="4877645476959324760">"Status bar"</string>
+ <string name="overview" msgid="4018602013895926956">"Overview"</string>
+ <string name="demo_mode" msgid="2532177350215638026">"System UI demo mode"</string>
+ <string name="enable_demo_mode" msgid="4844205668718636518">"Enable demo mode"</string>
+ <string name="show_demo_mode" msgid="2018336697782464029">"Show demo mode"</string>
+ <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string>
+ <string name="status_bar_alarm" msgid="8536256753575881818">"Alarm"</string>
+ <string name="status_bar_work" msgid="6022553324802866373">"Work profile"</string>
+ <string name="status_bar_airplane" msgid="7057575501472249002">"Airplane mode"</string>
+ <string name="add_tile" msgid="2995389510240786221">"Add tile"</string>
+ <string name="broadcast_tile" msgid="3894036511763289383">"Broadcast Tile"</string>
+ <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g> unless you turn this off before then"</string>
+ <string name="zen_alarm_warning" msgid="444533119582244293">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template" msgid="3980063409350522735">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template_far" msgid="4242179982586714810">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Quick Settings, <xliff:g id="TITLE">%s</xliff:g>."</string>
+ <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
+ <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work profile"</string>
+ <string name="tuner_warning_title" msgid="7094689930793031682">"Fun for some but not for all"</string>
+ <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
+ <string name="tuner_persistent_warning" msgid="8597333795565621795">"These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
+ <string name="got_it" msgid="2239653834387972602">"Got it"</string>
+ <string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string>
+ <string name="remove_from_settings" msgid="8389591916603406378">"Remove from Settings"</string>
+ <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
+ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
+ <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string>
+ <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string>
+ <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Turn on"</string>
+ <string name="show_silently" msgid="6841966539811264192">"Show notifications silently"</string>
+ <string name="block" msgid="2734508760962682611">"Block all notifications"</string>
+ <string name="do_not_silence" msgid="6878060322594892441">"Don\'t silence"</string>
+ <string name="do_not_silence_block" msgid="4070647971382232311">"Don\'t silence or block"</string>
+ <string name="tuner_full_importance_settings" msgid="3207312268609236827">"Power notification controls"</string>
+ <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"On"</string>
+ <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
+ <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
+ <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
+ <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
+ <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
+ <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+ <string name="notification_unblockable_desc" msgid="3561016061737896906">"Notifications from this app can\'t be turned off"</string>
+ <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+ <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
+ <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
+ </plurals>
+ <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+ <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+ <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, and <xliff:g id="NUMBER_5">%3$d</xliff:g> others</item>
+ <item quantity="one"><xliff:g id="CHANNEL_NAME_1_0">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_1">%2$s</xliff:g>, and <xliff:g id="NUMBER_2">%3$d</xliff:g> other</item>
+ </plurals>
+ <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> opened"</string>
+ <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Notification controls for <xliff:g id="APP_NAME">%1$s</xliff:g> closed"</string>
+ <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Allow notifications from this channel"</string>
+ <string name="notification_all_categories" msgid="5407190218055113282">"All Categories"</string>
+ <string name="notification_more_settings" msgid="816306283396553571">"More settings"</string>
+ <string name="notification_app_settings" msgid="3743278649182392015">"Customize: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
+ <string name="notification_done" msgid="5279426047273930175">"Done"</string>
+ <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
+ <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
+ <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
+ <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+ <plurals name="snoozeHourOptions" formatted="false" msgid="2124335842674413030">
+ <item quantity="other">%d hours</item>
+ <item quantity="one">%d hour</item>
+ </plurals>
+ <plurals name="snoozeMinuteOptions" formatted="false" msgid="4127251700591510196">
+ <item quantity="other">%d minutes</item>
+ <item quantity="one">%d minute</item>
+ </plurals>
+ <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
+ <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
+ <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
+ <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+ <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+ <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+ <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+ <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+ <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+ <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+ <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+ <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+ <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+ <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+ <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+ <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+ <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+ <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+ <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+ <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+ <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+ <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+ <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+ <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+ <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
+ <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string>
+ <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string>
+ <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Keyboard Shortcuts"</string>
+ <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Switch input method"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string>
+ <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assist"</string>
+ <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string>
+ <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string>
+ <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string>
+ <string name="keyboard_shortcut_group_applications_sms" msgid="638701213803242744">"SMS"</string>
+ <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string>
+ <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
+ <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string>
+ <string name="tuner_full_zen_title" msgid="4540823317772234308">"Show with volume controls"</string>
+ <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Do not disturb"</string>
+ <string name="volume_dnd_silent" msgid="4363882330723050727">"Volume buttons shortcut"</string>
+ <string name="volume_up_silent" msgid="7141255269783588286">"Exit do not disturb on volume up"</string>
+ <string name="battery" msgid="7498329822413202973">"Battery"</string>
+ <string name="clock" msgid="7416090374234785905">"Clock"</string>
+ <string name="headset" msgid="4534219457597457353">"Headset"</string>
+ <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphones connected"</string>
+ <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset connected"</string>
+ <string name="data_saver" msgid="5037565123367048522">"Data Saver"</string>
+ <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Data Saver is on"</string>
+ <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Data Saver is off"</string>
+ <string name="switch_bar_on" msgid="1142437840752794229">"On"</string>
+ <string name="switch_bar_off" msgid="8803270596930432874">"Off"</string>
+ <string name="nav_bar" msgid="1993221402773877607">"Navigation bar"</string>
+ <string name="nav_bar_layout" msgid="3664072994198772020">"Layout"</string>
+ <string name="left_nav_bar_button_type" msgid="8555981238887546528">"Extra left button type"</string>
+ <string name="right_nav_bar_button_type" msgid="2481056627065649656">"Extra right button type"</string>
+ <string name="nav_bar_default" msgid="8587114043070993007">"(default)"</string>
+ <string-array name="nav_bar_buttons">
+ <item msgid="1545641631806817203">"Clipboard"</item>
+ <item msgid="5742013440802239414">"Keycode"</item>
+ <item msgid="8802889973626281575">"Keyboard switcher"</item>
+ <item msgid="8175437057325747277">"None"</item>
+ </string-array>
+ <string-array name="nav_bar_layouts">
+ <item msgid="8077901629964902399">"Normal"</item>
+ <item msgid="8256205964297588988">"Compact"</item>
+ <item msgid="8719936228094005878">"Left-leaning"</item>
+ <item msgid="586019486955594690">"Right-leaning"</item>
+ </string-array>
+ <string name="menu_ime" msgid="4998010205321292416">"Keyboard switcher"</string>
+ <string name="save" msgid="2311877285724540644">"Save"</string>
+ <string name="reset" msgid="2448168080964209908">"Reset"</string>
+ <string name="adjust_button_width" msgid="6138616087197632947">"Adjust button width"</string>
+ <string name="clipboard" msgid="1313879395099896312">"Clipboard"</string>
+ <string name="accessibility_key" msgid="5701989859305675896">"Custom navigation button"</string>
+ <string name="left_keycode" msgid="2010948862498918135">"Left keycode"</string>
+ <string name="right_keycode" msgid="708447961000848163">"Right keycode"</string>
+ <string name="left_icon" msgid="3096287125959387541">"Left icon"</string>
+ <string name="right_icon" msgid="3952104823293824311">"Right icon"</string>
+ <string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
+ <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Drag here to remove"</string>
+ <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
+ <string name="tuner_time" msgid="6572217313285536011">"Time"</string>
+ <string-array name="clock_options">
+ <item msgid="5965318737560463480">"Show hours, minutes, and seconds"</item>
+ <item msgid="1427801730816895300">"Show hours and minutes (default)"</item>
+ <item msgid="3830170141562534721">"Don\'t show this icon"</item>
+ </string-array>
+ <string-array name="battery_options">
+ <item msgid="3160236755818672034">"Always show percentage"</item>
+ <item msgid="2139628951880142927">"Show percentage when charging (default)"</item>
+ <item msgid="3327323682209964956">"Don\'t show this icon"</item>
+ </string-array>
+ <string name="other" msgid="4060683095962566764">"Other"</string>
+ <string name="accessibility_divider" msgid="5903423481953635044">"Split-screen divider"</string>
+ <string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Left full screen"</string>
+ <string name="accessibility_action_divider_left_70" msgid="3612060638991687254">"Left 70%"</string>
+ <string name="accessibility_action_divider_left_50" msgid="1248083470322193075">"Left 50%"</string>
+ <string name="accessibility_action_divider_left_30" msgid="543324403127069386">"Left 30%"</string>
+ <string name="accessibility_action_divider_right_full" msgid="4639381073802030463">"Right full screen"</string>
+ <string name="accessibility_action_divider_top_full" msgid="5357010904067731654">"Top full screen"</string>
+ <string name="accessibility_action_divider_top_70" msgid="5090779195650364522">"Top 70%"</string>
+ <string name="accessibility_action_divider_top_50" msgid="6385859741925078668">"Top 50%"</string>
+ <string name="accessibility_action_divider_top_30" msgid="6201455163864841205">"Top 30%"</string>
+ <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"Bottom full screen"</string>
+ <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string>
+ <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string>
+ <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Position <xliff:g id="POSITION">%1$d</xliff:g>. Double tap to select."</string>
+ <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
+ <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Remove <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
+ <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is added to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
+ <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> is removed"</string>
+ <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> moved to position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
+ <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Quick settings editor."</string>
+ <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+ <string name="dock_forced_resizable" msgid="5914261505436217520">"App may not work with split-screen."</string>
+ <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App does not support split-screen."</string>
+ <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"App may not work on a secondary display."</string>
+ <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"App does not support launch on secondary displays."</string>
+ <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Open settings."</string>
+ <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Open quick settings."</string>
+ <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Close quick settings."</string>
+ <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Alarm set."</string>
+ <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_no_internet" msgid="31890692343084075">"No internet."</string>
+ <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Open details."</string>
+ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
+ <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string>
+ <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
+ <string name="tuner_lock_screen" msgid="5755818559638850294">"Lock screen"</string>
+ <string name="pip_phone_expand" msgid="5889780005575693909">"Expand"</string>
+ <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimize"</string>
+ <string name="pip_phone_close" msgid="8416647892889710330">"Close"</string>
+ <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Drag down to dismiss"</string>
+ <string name="pip_menu_title" msgid="3328510504196964712">"Picture in picture menu"</string>
+ <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> is in picture-in-picture"</string>
+ <string name="pip_notification_message" msgid="5619512781514343311">"If you don\'t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
+ <string name="pip_play" msgid="1417176722760265888">"Play"</string>
+ <string name="pip_pause" msgid="8881063404466476571">"Pause"</string>
+ <string name="pip_skip_to_next" msgid="1948440006726306284">"Skip to next"</string>
+ <string name="pip_skip_to_prev" msgid="1955311326688637914">"Skip to previous"</string>
+ <string name="thermal_shutdown_title" msgid="4458304833443861111">"Phone turned off due to heat"</string>
+ <string name="thermal_shutdown_message" msgid="9006456746902370523">"Your phone is now running normally"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n • Use resource-intensive apps (such as gaming, video, or navigation apps)\n • Download or upload large files\n • Use your phone in high temperatures"</string>
+ <string name="high_temp_title" msgid="4589508026407318374">"Phone is getting warm"</string>
+ <string name="high_temp_notif_message" msgid="5642466103153429279">"Some features limited while phone cools down"</string>
+ <string name="high_temp_dialog_message" msgid="6840700639374113553">"Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally."</string>
+ <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"Left shortcut"</string>
+ <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"Right shortcut"</string>
+ <string name="lockscreen_unlock_left" msgid="2043092136246951985">"Left shortcut also unlocks"</string>
+ <string name="lockscreen_unlock_right" msgid="1529992940510318775">"Right shortcut also unlocks"</string>
+ <string name="lockscreen_none" msgid="4783896034844841821">"None"</string>
+ <string name="tuner_launch_app" msgid="1527264114781925348">"Launch <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="tuner_other_apps" msgid="4726596850501162493">"Other apps"</string>
+ <string name="tuner_circle" msgid="2340998864056901350">"Circle"</string>
+ <string name="tuner_plus" msgid="6792960658533229675">"Plus"</string>
+ <string name="tuner_minus" msgid="4806116839519226809">"Minus"</string>
+ <string name="tuner_left" msgid="8404287986475034806">"Left"</string>
+ <string name="tuner_right" msgid="6222734772467850156">"Right"</string>
+ <string name="tuner_menu" msgid="191640047241552081">"Menu"</string>
+ <string name="tuner_app" msgid="3507057938640108777">"<xliff:g id="APP">%1$s</xliff:g> app"</string>
+ <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
+ <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
+ <string name="notification_channel_general" msgid="4525309436693914482">"General Messages"</string>
+ <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
+ <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+ <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
+ <string name="app_info" msgid="6856026610594615344">"App info"</string>
+ <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
+ <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
+ <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is off"</string>
+ <string name="dnd_is_off" msgid="6167780215212497572">"Do Not Disturb is off"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Do Not Disturb was turned on by an automatic rule (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Do Not Disturb was turned on by an app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Do Not Disturb was turned on by an automatic rule or app."</string>
+ <string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
+ <string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
+ <string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Turn off mobile data?"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings_car.xml b/packages/SystemUI/res/values-en-rXC/strings_car.xml
new file mode 100644
index 0000000..0aff34a
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+ <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings_tv.xml b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
new file mode 100644
index 0000000..c1c7adf
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+ <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
+ <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
+ <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 94f37b9..d5726df 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps que se ejecutan en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"¿Deseas desactivar los datos móviles?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c479cfe..a09d329 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplicaciones que se están ejecutando en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"¿Desactivar los datos móviles?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index a08a97a..810cc0d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Asenda"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Rakendusi käitatakse taustal"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Kas lülitada mobiilne andmeside välja?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 820fdb3..f3ab2fc 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Datu-konexioa desaktibatu nahi duzu?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0cf5530..c5d5645 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"جایگزین کردن"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"برنامههایی که در پسزمینه اجرا میشوند"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"داده شبکه تلفن همراه خاموش شود؟"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 638ca2e..f65d060 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Korvaa"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Sovelluksia käynnissä taustalla"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Poistetaanko mobiilidata käytöstä?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 25c448a..0150d62 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Applications qui fonctionnent en arrière-plan"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Désactiver les données cellulaires?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 44a26a6..bc22774 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Applications en cours d\'exécution en arrière-plan"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Désactiver les données mobiles ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 68d1c93..976c07e 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituír"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacións que se executan en segundo plano"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para obter información sobre o uso de datos e a batería"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Queres desactivar os datos móbiles?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 021ad3e..f81a473 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"બદલો"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"મોબાઇલ ડેટા બંધ કરીએ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index fa346af..21ff01d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"बदलें"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा उपयोग के विवरण देखने के लिए टैप करें"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा बंद करना चाहते हैं?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ea7ba5b..f872419 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -779,4 +779,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Izvođenje aplikacija u pozadini"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Isključiti mobilne podatke?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings_car.xml b/packages/SystemUI/res/values-hr/strings_car.xml
index d38620b..0a281d7 100644
--- a/packages/SystemUI/res/values-hr/strings_car.xml
+++ b/packages/SystemUI/res/values-hr/strings_car.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
- <string name="start_driving" msgid="864023351402918991">"Početak vožnje"</string>
+ <string name="start_driving" msgid="864023351402918991">"Započni vožnju"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a47daf5..bc4f9e3 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Csere"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"A háttérben még futnak alkalmazások"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Kikapcsolja a mobiladatokat?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 0dbee58..4935350 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -67,12 +67,12 @@
<string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Սարքի վրա այս պահին մուտք գործած օգտատերը չի կարող միացնել USB վրիպազերծումը: Այս գործառույթից օգտվելու համար մուտք գործեք ադմինիստրատորի հաշվով:"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Խոշորացնել` էկրանը լցնելու համար"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Ձգել` էկրանը լցնելու համար"</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Պահում է էկրանի հանույթը…"</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Պահում է էկրանի հանույթը..."</string>
- <string name="screenshot_saving_text" msgid="2419718443411738818">"Էկրանի հանույթը պահվում է:"</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի հանույթը լուսանկարվել է:"</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Պահում է էկրանի պատկերը…"</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Պահում է էկրանի պատկերը..."</string>
+ <string name="screenshot_saving_text" msgid="2419718443411738818">"Էկրանի պատկերը պահվում է:"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի պատկերը լուսանկարվել է:"</string>
<string name="screenshot_saved_text" msgid="2685605830386712477">"Հպեք՝ էկրանի պատկերը տեսնելու համար:"</string>
- <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string>
+ <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի պատկերը:"</string>
<string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Էկրանի պատկերը պահելիս խնդիր առաջացավ:"</string>
<string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Չհաջողվեց պահել էկրանի պատկերը սահմանափակ հիշողության պատճառով:"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում էկրանի պատկերի ստացումը"</string>
@@ -756,7 +756,7 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
<string name="notification_channel_screenshot" msgid="6314080179230000938">"Էկրանի պատկերներ"</string>
<string name="notification_channel_general" msgid="4525309436693914482">"Ընդհանուր հաղորդագրություններ"</string>
- <string name="notification_channel_storage" msgid="3077205683020695313">"Հիշողություն"</string>
+ <string name="notification_channel_storage" msgid="3077205683020695313">"Տարածք"</string>
<string name="instant_apps" msgid="6647570248119804907">"Ակնթարթորեն գործարկվող հավելվածներ"</string>
<string name="instant_apps_message" msgid="8116608994995104836">"Ակնթարթորեն գործարկվող հավելվածները տեղադրում չեն պահանջում։"</string>
<string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Փոխարինել"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Անջատե՞լ բջջային ինտերնետը։"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 12ff89d..ecb101b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikasi yang sedang berjalan di latar belakang"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail penggunaan baterai dan data"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Nonaktifkan data seluler?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 9100ca8..7ce154f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Skipta út"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Forrit sem keyra í bakgrunni"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Slökkva á farsímagögnum?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 134503b..f0bfdc3 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Sostituisci"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"App in esecuzione in background"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Disattivare i dati mobili?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index ba5816b..f2e5c40 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -785,4 +785,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"החלף"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"אפליקציות שפועלות ברקע"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"לכבות את חבילת הגלישה?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 8b86acc..f892538 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"設定を変更"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"バックグラウンドで実行中のアプリ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"タップして電池やデータの使用量を確認"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"モバイルデータを OFF にしますか?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 72c4215..489f18e 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ჩანაცვლება"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ფონურ რეჟიმში გაშვებული აპები"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"გსურთ მობილური ინტერნეტის გამორთვა?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 5d5f807..30bff78 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ауыстыру"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Фонда жұмыс істеп тұрған қолданбалар"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобильдік деректер өшірілсін бе?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index e161f59..4c470a7 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ជំនួស"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"បិទទិន្នន័យចល័ត?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 2284c9b..c9040e7 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ಬದಲಿಸಿ"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ಮೊಬೈಲ್ ಡೇಟಾ ಆಫ್ ಮಾಡಬೇಕೆ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 31cc047..87a4cf9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -674,7 +674,7 @@
<string name="left_icon" msgid="3096287125959387541">"왼쪽 아이콘"</string>
<string name="right_icon" msgid="3952104823293824311">"오른쪽 아이콘"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"드래그하여 타일 추가"</string>
- <string name="drag_to_remove_tiles" msgid="3361212377437088062">"삭제하려면 여기를 드래그"</string>
+ <string name="drag_to_remove_tiles" msgid="3361212377437088062">"여기로 드래그하여 삭제"</string>
<string name="qs_edit" msgid="2232596095725105230">"수정"</string>
<string name="tuner_time" msgid="6572217313285536011">"시간"</string>
<string-array name="clock_options">
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"바꾸기"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"백그라운드에서 실행 중인 앱"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"탭하여 배터리 및 데이터 사용량 확인"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"모바일 데이터를 사용 중지하시겠습니까?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index f3d5dbd..5a6228d 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Алмаштыруу"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Фондо иштеп жаткан колдонмолор"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобилдик Интернетти өчүрөсүзбү?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a5f0ca4..851d797 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ແທນທີ່"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ປິດອິນເຕີເນັດມືຖືໄວ້ບໍ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c1ccc75..e68b8b4 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -785,4 +785,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Pakeisti"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Programos, veikiančios fone"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Išjungti mobiliojo ryšio duomenis?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4d4aad1..d223241 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -779,4 +779,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Aizstāt"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Lietotnes, kas darbojas fonā"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vai izslēgt mobilos datus?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index fb7c7af..f3e6bd7 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Апликациите се извршуваат во заднина"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Да се исклучи мобилниот интернет?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index b42319a..d87ffb9 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"മാറ്റിസ്ഥാപിക്കുക"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"മൊബൈൽ ഡാറ്റ ഓഫാക്കണോ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index cd4f5be..786cd54 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Солих"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Цаана ажиллаж буй апп"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Мобайл датаг унтраах уу?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index b8562f6..9fe0975 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"पुनर्स्थित करा"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"अॅप्स बॅकग्राउंडमध्ये चालू आहेत"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"बॅटरी आणि डेटा वापराच्या तपशीलांसाठी टॅप करा"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा बंद करायचा?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 2c2e094..4a70d9e 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Gantikan"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apl yang berjalan di latar belakang"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Matikan data mudah alih?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 5040bfd..95d95c8 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"အစားထိုးရန်"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"မိုဘိုင်းဒေတာကို ပိတ်လိုပါသလား။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 324c583..0449627 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstatt"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apper kjører i bakgrunnen"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Trykk for detaljer om batteri- og databruk"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vil du slå av mobildata?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index d2a5020..b3ae2d0 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"प्रतिस्थापन गर्नुहोस्"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index d6a949d..1bd30da 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervangen"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps uitgevoerd op achtergrond"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik voor batterij- en datagebruik"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobiele data uitschakelen?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c321759..daf6345 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ਬਦਲੋ"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ਮੋਬਾਈਲ ਡੈਟਾ ਬੰਦ ਕਰੀਏ?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 279d121..b1a024a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -785,4 +785,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zastąp"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacje działające w tle"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i transmisji danych"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Wyłączyć mobilną transmisję danych?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0b7e8b01..746a7fd 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Apps sendo executados em segundo plano"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Desativar os dados móveis?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 0224ef5..7620c71 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -781,4 +781,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Înlocuiți"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplicațiile rulează în fundal"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Dezactivați datele mobile?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index f8dc744..b44d7d6 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Заменить"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работающие в фоновом режиме"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Отключить мобильный Интернет?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 7e77c43..15b4446 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"ප්රතිස්ථාපනය"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ජංගම දත්ත ක්රියාවිරහිත කරන්නද?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 2b19d6f..58e4b8a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradiť"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikácie sú spustené na pozadí"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vypnúť mobilné dáta?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 29dfa3a..8c03d0e 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamenjaj"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije, ki se izvajajo v ozadju"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Dotaknite se za prikaz podrobnosti porabe akumulatorja in prenosa podatkov"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Želite izklopiti prenos podatkov v mobilnih omrežjih?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 0423208..607440d 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zëvendëso"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacionet që ekzekutohen në sfond"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Të çaktivizohen të dhënat celulare?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d6adcb5..8db53af8 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -779,4 +779,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Апликације покренуте у позадини"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Додирните за детаље о батерији и потрошњи података"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Желите да онемогућите мобилне податке?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 642484f..f318be1 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersätt"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Appar körs i bakgrunden"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryck för information om batteri- och dataanvändning"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vill du inaktivera mobildatan?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index f567ec9..87a3d77e 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Badilisha"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Programu zinatumika chinichini"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Gonga ili upate maelezo kuhusu betri na matumizi ya data"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Ungependa kuzima data ya mtandao wa simu?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e0a0e9b..10f3a3b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"மாற்று"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் தரவு உபயோக விவரங்களைக் காண, தட்டவும்"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"மொபைல் தரவை முடக்கவா?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 1787d07..01cbfed 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"భర్తీ చేయి"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"నేపథ్యంలో అమలు అవుతున్న ఆప్లు"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"మొబైల్ డేటాని ఆఫ్ చేయాలా?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index a0db287..2a9f4d8 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"แทนที่"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ปิดอินเทอร์เน็ตมือถือไหม"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 5b6732c..59d3f62 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Palitan"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Tumatakbo ang mga app sa background"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"I-off ang mobile data?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index ad6c498..78ded20 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Değiştir"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Arka planda çalışan uygulamalar"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil veri kapatılsın mı?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7866c8f..e126f7c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -787,4 +787,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Замінити"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Додатки, які працюють у фоновому режимі"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Вимкнути мобільний трафік?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c59242f..12c4560 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"بدلیں"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"ایپس پس منظر میں چل رہی ہیں"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"موبائل ڈیٹا آف کریں؟"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 4946f69..c632914 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Almashtirish"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Fonda ishlayotgan ilovalar"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Mobil internet o‘chirib qo‘yilsinmi?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index e716899..9ae0e77 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Thay thế"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Ứng dụng đang chạy trong nền"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Tắt dữ liệu di động?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b8588d9..89148c8 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"替换"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"在后台运行的应用"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"点按即可详细了解电量和流量消耗情况"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要关闭移动数据网络吗?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e29ccb6..91ec22f 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -775,4 +775,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"正在背景中執行的應用程式"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"輕按即可查看電池和數據用量詳情"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要關閉流動數據嗎?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2656550..6a9ee7e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"在背景執行的應用程式"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"輕觸即可查看電池和數據用量詳情"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"要關閉行動數據嗎?"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e66ff73..9ea4f21 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -773,4 +773,5 @@
<string name="qs_dnd_replace" msgid="8019520786644276623">"Buyisela"</string>
<string name="running_foreground_services_title" msgid="381024150898615683">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
+ <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Vala idatha yeselula?"</string>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 054d520..f72f379 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -116,11 +116,11 @@
<color name="segmented_buttons_background">#14FFFFFF</color><!-- 8% white -->
<color name="dark_mode_icon_color_single_tone">#99000000</color>
- <color name="dark_mode_icon_color_dual_tone_background">#4d000000</color>
+ <color name="dark_mode_icon_color_dual_tone_background">#3d000000</color>
<color name="dark_mode_icon_color_dual_tone_fill">#7a000000</color>
<color name="light_mode_icon_color_single_tone">#ffffff</color>
- <color name="light_mode_icon_color_dual_tone_background">#5dffffff</color>
+ <color name="light_mode_icon_color_dual_tone_background">#4dffffff</color>
<color name="light_mode_icon_color_dual_tone_fill">#ffffff</color>
<color name="volume_settings_icon_color">#7fffffff</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b0ee039..506c294 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -267,14 +267,27 @@
<!-- Doze: alpha to apply to small icons when dozing -->
<integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
- <!-- Doze: the brightness value to use for the lower brightness AOD mode -->
- <integer name="config_doze_aod_brightness_low">5</integer>
+ <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+ to brightness values; -1 means keeping the current brightness. -->
+ <integer-array name="config_doze_brightness_sensor_to_brightness">
+ <item>-1</item> <!-- 0: OFF -->
+ <item>2</item> <!-- 1: NIGHT -->
+ <item>5</item> <!-- 2: LOW -->
+ <item>27</item> <!-- 3: HIGH -->
+ <item>28</item> <!-- 4: SUN -->
+ </integer-array>
- <!-- Doze: the brightness value to use for the higher brightness AOD mode -->
- <integer name="config_doze_aod_brightness_high">27</integer>
-
- <!-- Doze: the brightness value to use for the sunlight AOD mode -->
- <integer name="config_doze_aod_brightness_sunlight">28</integer>
+ <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+ to an opacity value for a black scrim that is overlayed in AOD1.
+ Valid range is from 0 (transparent) to 255 (opaque).
+ -1 means keeping the current opacity. -->
+ <integer-array name="config_doze_brightness_sensor_to_scrim_opacity">
+ <item>-1</item> <!-- 0: OFF -->
+ <item>0</item> <!-- 1: NIGHT -->
+ <item>0</item> <!-- 2: LOW -->
+ <item>0</item> <!-- 3: HIGH -->
+ <item>0</item> <!-- 4: SUN -->
+ </integer-array>
<!-- Doze: whether the double tap sensor reports 2D touch coordinates -->
<bool name="doze_double_tap_reports_touch_coordinates">false</bool>
@@ -396,4 +409,8 @@
one bar higher than they actually are -->
<bool name="config_inflateSignalStrength">false</bool>
+ <!-- Should we vibrate on an icon animation of the shelf. This should only be active if the
+ vibrator is capable of subtle vibrations -->
+ <bool name="config_vibrateOnIconAnimation">false</bool>
+
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dca021e..2199fff 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -307,6 +307,9 @@
<item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
<item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
<item name="passwordStyle">@style/PasswordTheme</item>
+
+ <!-- Needed for MediaRoute chooser dialog -->
+ <item name="*android:isLightTheme">false</item>
</style>
<style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index e5c729f..9c1cb4e 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -16,6 +16,7 @@
import android.content.Context;
import android.content.res.Configuration;
+import android.hardware.SensorManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -84,6 +85,7 @@
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerServiceImpl;
+import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.leak.LeakReporter;
@@ -156,6 +158,9 @@
mProviders.put(ActivityStarterDelegate.class, () ->
getDependency(ActivityStarter.class));
+ mProviders.put(AsyncSensorManager.class, () ->
+ new AsyncSensorManager(mContext.getSystemService(SensorManager.class)));
+
mProviders.put(BluetoothController.class, () ->
new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER)));
diff --git a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
index 6296297..9fe730a 100644
--- a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
@@ -74,8 +74,11 @@
private static void onDockedStackExistsChanged(boolean exists) {
synchronized (sCallbacks) {
- sCallbacks.removeIf(wf -> wf.get() == null);
- sCallbacks.forEach(wf -> wf.get().accept(exists));
+ sCallbacks.removeIf(wf -> {
+ Consumer<Boolean> l = wf.get();
+ if (l != null) l.accept(exists);
+ return l == null;
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
index 40ea4ec..5d31678 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -24,6 +24,7 @@
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
@@ -69,12 +70,14 @@
mOverlay = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners, null);
mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ mOverlay.setAlpha(0);
mOverlay.findViewById(R.id.right).setRotation(90);
mContext.getSystemService(WindowManager.class)
.addView(mOverlay, getWindowLayoutParams());
mBottomOverlay = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners, null);
+ mBottomOverlay.setAlpha(0);
mBottomOverlay.findViewById(R.id.right).setRotation(180);
mBottomOverlay.findViewById(R.id.left).setRotation(270);
WindowManager.LayoutParams layoutParams = getWindowLayoutParams();
@@ -88,6 +91,23 @@
mDensity = metrics.density;
Dependency.get(TunerService.class).addTunable(this, SIZE);
+
+ mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft,
+ int oldTop, int oldRight, int oldBottom) {
+ mOverlay.removeOnLayoutChangeListener(this);
+ mOverlay.animate()
+ .alpha(1)
+ .setDuration(1000)
+ .start();
+ mBottomOverlay.animate()
+ .alpha(1)
+ .setDuration(1000)
+ .start();
+ }
+ });
}
private void setupPadding(int padding) {
@@ -119,7 +139,7 @@
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS
- | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT;
+ | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
lp.setTitle("RoundedOverlay");
lp.gravity = Gravity.TOP;
return lp;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 5237244..0c067ff 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -40,6 +40,8 @@
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.volume.VolumeDialogControllerImpl;
+import java.util.function.Consumer;
+
/**
* Class factory to provide customizable SystemUI components.
*/
@@ -84,8 +86,10 @@
public ScrimController createScrimController(LightBarController lightBarController,
ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
- LockscreenWallpaper lockscreenWallpaper) {
- return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim);
+ LockscreenWallpaper lockscreenWallpaper,
+ Consumer<Boolean> scrimVisibleListener) {
+ return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
+ scrimVisibleListener);
}
public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index e92ed2f..e4b405f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -35,6 +35,7 @@
import com.android.systemui.UiOffloadThread;
import com.android.systemui.analytics.DataCollector;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.AsyncSensorManager;
import java.io.PrintWriter;
@@ -87,7 +88,7 @@
private FalsingManager(Context context) {
mContext = context;
- mSensorManager = mContext.getSystemService(SensorManager.class);
+ mSensorManager = Dependency.get(AsyncSensorManager.class);
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mDataCollector = DataCollector.getInstance(mContext);
mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index fe8373f..34c05a5 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -21,6 +21,8 @@
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.Trace;
+import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
import android.view.IWallpaperVisibilityListener;
@@ -31,11 +33,17 @@
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.types.ExtractionType;
import com.android.internal.colorextraction.types.Tonal;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
/**
* ColorExtractor aware of wallpaper visibility
*/
-public class SysuiColorExtractor extends ColorExtractor {
+public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
private static final String TAG = "SysuiColorExtractor";
private boolean mWallpaperVisible;
// Colors to return when the wallpaper isn't visible
@@ -70,6 +78,14 @@
Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
}
}
+
+ WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
+ if (wallpaperManager != null) {
+ // Listen to all users instead of only the current one.
+ wallpaperManager.removeOnColorsChangedListener(this);
+ wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+ UserHandle.USER_ALL);
+ }
}
private void updateDefaultGradients(WallpaperColors colors) {
@@ -77,7 +93,12 @@
}
@Override
- public void onColorsChanged(WallpaperColors colors, int which) {
+ public void onColorsChanged(WallpaperColors colors, int which, int userId) {
+ if (userId != KeyguardUpdateMonitor.getCurrentUser()) {
+ // Colors do not belong to current user, ignoring.
+ return;
+ }
+
super.onColorsChanged(colors, which);
if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
@@ -134,6 +155,11 @@
* @return colors
*/
public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
+ // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
+ // if we have different lock and system wallpapers.
+ if (which == WallpaperManager.FLAG_LOCK) {
+ ignoreWallpaperVisibility = true;
+ }
if (mWallpaperVisible || ignoreWallpaperVisibility) {
return super.getColors(which, type);
} else {
@@ -149,4 +175,20 @@
}
}
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("SysuiColorExtractor:");
+
+ pw.println(" Current wallpaper colors:");
+ pw.println(" system: " + mSystemColors);
+ pw.println(" lock: " + mLockColors);
+
+ GradientColors[] system = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+ GradientColors[] lock = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+ pw.println(" Gradients:");
+ pw.println(" system: " + Arrays.toString(system));
+ pw.println(" lock: " + Arrays.toString(lock));
+ pw.println(" Default scrim: " + mWpHiddenColors);
+
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 91ca571..302bc2d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -24,10 +24,12 @@
import android.os.Handler;
import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
@@ -39,7 +41,7 @@
/** Creates a DozeMachine with its parts for {@code dozeService}. */
public DozeMachine assembleMachine(DozeService dozeService) {
Context context = dozeService;
- SensorManager sensorManager = context.getSystemService(SensorManager.class);
+ SensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
DozeHost host = getHost(dozeService);
@@ -63,7 +65,7 @@
handler, wakeLock, machine),
createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
createDozeScreenState(wrappedService),
- createDozeScreenBrightness(context, wrappedService, sensorManager, handler),
+ createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
});
return machine;
@@ -74,10 +76,11 @@
}
private DozeMachine.Part createDozeScreenBrightness(Context context,
- DozeMachine.Service service, SensorManager sensorManager, Handler handler) {
+ DozeMachine.Service service, SensorManager sensorManager, DozeHost host,
+ Handler handler) {
Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
context.getString(R.string.doze_brightness_sensor_type));
- return new DozeScreenBrightness(context, service, sensorManager, sensor, handler);
+ return new DozeScreenBrightness(context, service, sensorManager, sensor, host, handler);
}
private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 57fb14e..7db118d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -42,8 +42,11 @@
void onDoubleTap(float x, float y);
+ default void setAodDimmingScrim(float scrimOpacity) {}
void setDozeScreenBrightness(int value);
+ void onIgnoreTouchWhilePulsing(boolean ignore);
+
interface Callback {
default void onNotificationHeadsUp() {}
default void onPowerSaveChanged(boolean active) {}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 0993ace..79de48a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -164,6 +164,11 @@
}
}
+ public static void traceState(DozeMachine.State state) {
+ if (!ENABLED) return;
+ log("state " + state);
+ }
+
public static void traceProximityResult(Context context, boolean near, long millis,
int pulseReason) {
if (!ENABLED) return;
@@ -233,10 +238,10 @@
+ state + " blocked=" + blocked);
}
- public static void tracePulseCanceledByProx(Context context) {
+ public static void tracePulseTouchDisabledByProx(Context context, boolean disabled) {
if (!ENABLED) return;
init(context);
- log("pulseCanceledByProx");
+ log("pulseTouchDisabledByProx " + disabled);
}
public static void setRegisterKeyguardCallback(boolean registerKeyguardCallback) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index a1dfeb3..8ec6afc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -17,6 +17,7 @@
package com.android.systemui.doze;
import android.annotation.MainThread;
+import android.os.Trace;
import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
@@ -225,6 +226,9 @@
State oldState = mState;
mState = newState;
+ DozeLog.traceState(newState);
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "doze_machine_state", newState.ordinal());
+
updatePulseReason(newState, oldState, pulseReason);
performTransitionOnComponents(oldState, newState);
updateWakeLockState(newState);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index ed4b131..30420529 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -32,29 +32,28 @@
public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListener {
private final Context mContext;
private final DozeMachine.Service mDozeService;
+ private final DozeHost mDozeHost;
private final Handler mHandler;
private final SensorManager mSensorManager;
private final Sensor mLightSensor;
+ private final int[] mSensorToBrightness;
+ private final int[] mSensorToScrimOpacity;
private boolean mRegistered;
- private final int mHighBrightness;
- private final int mLowBrightness;
- private final int mSunlightBrightness;
-
public DozeScreenBrightness(Context context, DozeMachine.Service service,
- SensorManager sensorManager, Sensor lightSensor, Handler handler) {
+ SensorManager sensorManager, Sensor lightSensor, DozeHost host,
+ Handler handler) {
mContext = context;
mDozeService = service;
mSensorManager = sensorManager;
mLightSensor = lightSensor;
+ mDozeHost = host;
mHandler = handler;
- mLowBrightness = context.getResources().getInteger(
- R.integer.config_doze_aod_brightness_low);
- mHighBrightness = context.getResources().getInteger(
- R.integer.config_doze_aod_brightness_high);
- mSunlightBrightness = context.getResources().getInteger(
- R.integer.config_doze_aod_brightness_sunlight);
+ mSensorToBrightness = context.getResources().getIntArray(
+ R.array.config_doze_brightness_sensor_to_brightness);
+ mSensorToScrimOpacity = context.getResources().getIntArray(
+ R.array.config_doze_brightness_sensor_to_scrim_opacity);
}
@Override
@@ -81,21 +80,31 @@
@Override
public void onSensorChanged(SensorEvent event) {
if (mRegistered) {
- mDozeService.setDozeScreenBrightness(computeBrightness((int) event.values[0]));
+ int sensorValue = (int) event.values[0];
+ int brightness = computeBrightness(sensorValue);
+ if (brightness > 0) {
+ mDozeService.setDozeScreenBrightness(brightness);
+ }
+
+ int scrimOpacity = computeScrimOpacity(sensorValue);
+ if (scrimOpacity >= 0) {
+ mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
+ }
}
}
- private int computeBrightness(int sensorValue) {
- // The sensor reports 0 for off, 1 for low brightness, 2 for high brightness, and 3 for
- // sunlight. We currently use DozeScreenState for screen off, so we treat off as low
- // brightness.
- if (sensorValue >= 3) {
- return mSunlightBrightness;
- } else if (sensorValue == 2) {
- return mHighBrightness;
- } else {
- return mLowBrightness;
+ private int computeScrimOpacity(int sensorValue) {
+ if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) {
+ return -1;
}
+ return mSensorToScrimOpacity[sensorValue];
+ }
+
+ private int computeBrightness(int sensorValue) {
+ if (sensorValue < 0 || sensorValue >= mSensorToBrightness.length) {
+ return -1;
+ }
+ return mSensorToBrightness[sensorValue];
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index bf1c060..566353c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -87,25 +87,29 @@
mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
null /* setting */,
dozeParameters.getPulseOnSigMotion(),
- DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */),
+ DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+ false /* touchscreen */),
mPickupSensor = new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Settings.Secure.DOZE_PULSE_ON_PICK_UP,
config.pulseOnPickupAvailable(),
- DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */),
+ DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */,
+ false /* touchscreen */),
new TriggerSensor(
findSensorWithType(config.doubleTapSensorType()),
Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
true /* configured */,
DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP,
- dozeParameters.doubleTapReportsTouchCoordinates()),
+ dozeParameters.doubleTapReportsTouchCoordinates(),
+ true /* touchscreen */),
new TriggerSensor(
findSensorWithType(config.longPressSensorType()),
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
false /* settingDef */,
true /* configured */,
DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
- true /* reports touch coordinates */),
+ true /* reports touch coordinates */,
+ true /* touchscreen */),
};
mProxSensor = new ProxSensor();
@@ -141,6 +145,15 @@
}
}
+ /** Set the listening state of only the sensors that require the touchscreen. */
+ public void setTouchscreenSensorsListening(boolean listening) {
+ for (TriggerSensor sensor : mSensors) {
+ if (sensor.mRequiresTouchscreen) {
+ sensor.setListening(listening);
+ }
+ }
+ }
+
public void reregisterAllSensors() {
for (TriggerSensor s : mSensors) {
s.setListening(false);
@@ -278,25 +291,28 @@
final String mSetting;
final boolean mReportsTouchCoordinates;
final boolean mSettingDefault;
+ final boolean mRequiresTouchscreen;
private boolean mRequested;
private boolean mRegistered;
private boolean mDisabled;
public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
- boolean reportsTouchCoordinates) {
+ boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
this(sensor, setting, true /* settingDef */, configured, pulseReason,
- reportsTouchCoordinates);
+ reportsTouchCoordinates, requiresTouchscreen);
}
public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
- boolean configured, int pulseReason, boolean reportsTouchCoordinates) {
+ boolean configured, int pulseReason, boolean reportsTouchCoordinates,
+ boolean requiresTouchscreen) {
mSensor = sensor;
mSetting = setting;
mSettingDefault = settingDef;
mConfigured = configured;
mPulseReason = pulseReason;
mReportsTouchCoordinates = reportsTouchCoordinates;
+ mRequiresTouchscreen = requiresTouchscreen;
}
public void setListening(boolean listen) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index ea06479..4583160 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -162,10 +162,10 @@
final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
final boolean aod = (state == DozeMachine.State.DOZE_AOD);
- if (near && state == DozeMachine.State.DOZE_PULSING) {
- if (DEBUG) Log.i(TAG, "Prox NEAR, ending pulse");
- DozeLog.tracePulseCanceledByProx(mContext);
- mMachine.requestState(DozeMachine.State.DOZE_PULSE_DONE);
+ if (state == DozeMachine.State.DOZE_PULSING) {
+ boolean ignoreTouch = near;
+ if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+ mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
}
if (far && (paused || pausing)) {
if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
@@ -198,6 +198,7 @@
mDozeSensors.setListening(false);
break;
case DOZE_PULSING:
+ mDozeSensors.setTouchscreenSensorsListening(false);
mDozeSensors.setProxListening(true);
break;
case FINISH:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 1dc37cd..dc626fb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -95,18 +95,22 @@
unscheduleTimeTick();
break;
}
- mHost.setAnimateWakeup(shouldAnimateWakeup(newState));
+ updateAnimateWakeup(newState);
}
- private boolean shouldAnimateWakeup(DozeMachine.State state) {
+ private void updateAnimateWakeup(DozeMachine.State state) {
switch (state) {
- case DOZE_AOD:
case DOZE_REQUEST_PULSE:
case DOZE_PULSING:
case DOZE_PULSE_DONE:
- return true;
+ mHost.setAnimateWakeup(true);
+ break;
+ case FINISH:
+ // Keep current state.
+ break;
default:
- return false;
+ mHost.setAnimateWakeup(false);
+ break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index f07027e..09a08f0 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -46,6 +46,11 @@
}
@Override
+ public void handleShowShutdownUi(boolean isReboot, String reason) {
+ mExtension.get().showShutdownUi(isReboot, reason);
+ }
+
+ @Override
public void handleShowGlobalActionsMenu() {
mExtension.get().showGlobalActions(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 7799c01..33d5617 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -116,8 +116,6 @@
private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
- private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
-
private final Context mContext;
private final GlobalActionsManager mWindowManagerFuncs;
private final AudioManager mAudioManager;
@@ -682,10 +680,7 @@
/** {@inheritDoc} */
public void onClick(DialogInterface dialog, int which) {
Action item = mAdapter.getItem(which);
- if ((item instanceof PowerAction)
- || (item instanceof RestartAction)) {
- if (mDialog != null) mDialog.fadeOut();
- } else if (!(item instanceof SilentModeTriStateAction)) {
+ if (!(item instanceof SilentModeTriStateAction)) {
dialog.dismiss();
}
item.onPress();
@@ -1325,23 +1320,6 @@
.start();
}
- public void fadeOut() {
- mHardwareLayout.setTranslationX(0);
- mHardwareLayout.setAlpha(1);
- mListView.animate()
- .alpha(0)
- .translationX(getAnimTranslation())
- .setDuration(300)
- .setInterpolator(new LogAccelerateInterpolator())
- .setUpdateListener(animation -> {
- float frac = animation.getAnimatedFraction();
- float alpha = NotificationUtils.interpolate(
- ScrimController.GRADIENT_SCRIM_ALPHA, SHUTDOWN_SCRIM_ALPHA, frac);
- mGradientDrawable.setAlpha((int) (alpha * 255));
- })
- .start();
- }
-
private float getAnimTranslation() {
return getContext().getResources().getDimension(
com.android.systemui.R.dimen.global_actions_panel_width) / 2;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 08b7b71..2cf230c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -14,17 +14,33 @@
package com.android.systemui.globalactions;
+import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import android.content.Context;
-import android.support.v7.view.ContextThemeWrapper;
-
public class GlobalActionsImpl implements GlobalActions {
+ private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
+
private final Context mContext;
private final KeyguardMonitor mKeyguardMonitor;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -44,4 +60,51 @@
mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned());
}
+
+ @Override
+ public void showShutdownUi(boolean isReboot, String reason) {
+ GradientDrawable background = new GradientDrawable(mContext);
+ background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255));
+
+ Dialog d = new Dialog(mContext,
+ com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+ // Window initialization
+ Window window = d.getWindow();
+ window.getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT;
+ window.getAttributes().height = ViewGroup.LayoutParams.MATCH_PARENT;
+ window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+ window.requestFeature(Window.FEATURE_NO_TITLE);
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+ | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+ window.addFlags(
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+ window.setBackgroundDrawable(background);
+ window.setWindowAnimations(R.style.Animation_Toast);
+
+ d.setContentView(R.layout.shutdown_dialog);
+ d.setCancelable(false);
+
+ int color = Utils.getColorAttr(mContext, com.android.systemui.R.attr.wallpaperTextColor);
+ boolean onKeyguard = mContext.getSystemService(
+ KeyguardManager.class).isKeyguardLocked();
+
+ ProgressBar bar = d.findViewById(R.id.progress);
+ bar.getIndeterminateDrawable().setTint(color);
+ TextView message = d.findViewById(R.id.text1);
+ message.setTextColor(color);
+ if (isReboot) message.setText(R.string.reboot_to_reset_message);
+
+ Point displaySize = new Point();
+ mContext.getDisplay().getRealSize(displaySize);
+ GradientColors colors = Dependency.get(SysuiColorExtractor.class).getColors(
+ onKeyguard ? WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
+ background.setColors(colors, false);
+ background.setScreenSize(displaySize.x, displaySize.y);
+
+ d.show();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
index 3f39dfe..b6fce44 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
@@ -16,6 +16,8 @@
package com.android.systemui.keyguard;
+import android.os.Trace;
+
import com.android.systemui.Dumpable;
import java.io.FileDescriptor;
@@ -38,22 +40,22 @@
}
public void dispatchScreenTurningOn() {
- mScreenState = SCREEN_TURNING_ON;
+ setScreenState(SCREEN_TURNING_ON);
dispatch(Observer::onScreenTurningOn);
}
public void dispatchScreenTurnedOn() {
- mScreenState = SCREEN_ON;
+ setScreenState(SCREEN_ON);
dispatch(Observer::onScreenTurnedOn);
}
public void dispatchScreenTurningOff() {
- mScreenState = SCREEN_TURNING_OFF;
+ setScreenState(SCREEN_TURNING_OFF);
dispatch(Observer::onScreenTurningOff);
}
public void dispatchScreenTurnedOff() {
- mScreenState = SCREEN_OFF;
+ setScreenState(SCREEN_OFF);
dispatch(Observer::onScreenTurnedOff);
}
@@ -63,6 +65,11 @@
pw.println(" mScreenState=" + mScreenState);
}
+ private void setScreenState(int screenState) {
+ mScreenState = screenState;
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "screenState", screenState);
+ }
+
public interface Observer {
default void onScreenTurningOn() {}
default void onScreenTurnedOn() {}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index 578e6fb..951c0ea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -16,6 +16,8 @@
package com.android.systemui.keyguard;
+import android.os.Trace;
+
import com.android.systemui.Dumpable;
import java.io.FileDescriptor;
@@ -39,22 +41,22 @@
}
public void dispatchStartedWakingUp() {
- mWakefulness = WAKEFULNESS_WAKING;
+ setWakefulness(WAKEFULNESS_WAKING);
dispatch(Observer::onStartedWakingUp);
}
public void dispatchFinishedWakingUp() {
- mWakefulness = WAKEFULNESS_AWAKE;
+ setWakefulness(WAKEFULNESS_AWAKE);
dispatch(Observer::onFinishedWakingUp);
}
public void dispatchStartedGoingToSleep() {
- mWakefulness = WAKEFULNESS_GOING_TO_SLEEP;
+ setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
dispatch(Observer::onStartedGoingToSleep);
}
public void dispatchFinishedGoingToSleep() {
- mWakefulness = WAKEFULNESS_ASLEEP;
+ setWakefulness(WAKEFULNESS_ASLEEP);
dispatch(Observer::onFinishedGoingToSleep);
}
@@ -64,6 +66,11 @@
pw.println(" mWakefulness=" + mWakefulness);
}
+ private void setWakefulness(int wakefulness) {
+ mWakefulness = wakefulness;
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
+ }
+
public interface Observer {
default void onStartedWakingUp() {}
default void onFinishedWakingUp() {}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
index 6733421..abc5667 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
@@ -65,7 +65,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
boolean handled = true;
try {
// To be implemented for input handling over Pip windows
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a642077..a913999 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -22,6 +22,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.BatteryManager;
@@ -56,6 +58,7 @@
private PowerManager mPowerManager;
private HardwarePropertiesManager mHardwarePropertiesManager;
private WarningsUI mWarnings;
+ private final Configuration mLastConfiguration = new Configuration();
private int mBatteryLevel = 100;
private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
private int mPlugType = 0;
@@ -71,6 +74,11 @@
private int mNumTemps;
private long mNextLogTime;
+ // We create a method reference here so that we are guaranteed that we can remove a callback
+ // by using the same instance (method references are not guaranteed to be the same object
+ // each time they are created).
+ private final Runnable mUpdateTempCallback = this::updateTemperatureWarning;
+
public void start() {
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mHardwarePropertiesManager = (HardwarePropertiesManager)
@@ -80,6 +88,7 @@
mContext,
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE),
getComponent(StatusBar.class));
+ mLastConfiguration.setTo(mContext.getResources().getConfiguration());
ContentObserver obs = new ContentObserver(mHandler) {
@Override
@@ -101,6 +110,16 @@
initTemperatureWarning();
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ final int mask = ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC;
+
+ // Safe to modify mLastConfiguration here as it's only updated by the main thread (here).
+ if ((mLastConfiguration.updateFrom(newConfig) & mask) != 0) {
+ mHandler.post(this::initTemperatureWarning);
+ }
+ }
+
void updateBatteryWarningLevels() {
int critLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -255,8 +274,14 @@
}
mThresholdTemp = throttlingTemps[0];
}
+
setNextLogTime();
+ // This initialization method may be called on a configuration change. Only one set of
+ // ongoing callbacks should be occurring, so remove any now. updateTemperatureWarning will
+ // schedule an ongoing callback.
+ mHandler.removeCallbacks(mUpdateTempCallback);
+
// We have passed all of the checks, start checking the temp
updateTemperatureWarning();
}
@@ -288,7 +313,7 @@
logTemperatureStats();
- mHandler.postDelayed(this::updateTemperatureWarning, TEMPERATURE_INTERVAL);
+ mHandler.postDelayed(mUpdateTempCallback, TEMPERATURE_INTERVAL);
}
private void logAtTemperatureThreshold(float temp) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 697db5f..10514a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -287,11 +287,17 @@
mScanState = state;
final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
if (state) {
- mQsDetailHeaderProgress.animate().alpha(1f);
- anim.start();
+ mQsDetailHeaderProgress.animate().cancel();
+ mQsDetailHeaderProgress.animate()
+ .alpha(1)
+ .withEndAction(anim::start)
+ .start();
} else {
- mQsDetailHeaderProgress.animate().alpha(0f);
- anim.stop();
+ mQsDetailHeaderProgress.animate().cancel();
+ mQsDetailHeaderProgress.animate()
+ .alpha(0f)
+ .withEndAction(anim::stop)
+ .start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index c4d88ae..8f41084 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -46,6 +46,7 @@
import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSliderView;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -53,7 +54,7 @@
import java.util.Collection;
/** View that represents the quick settings tile panel. **/
-public class QSPanel extends LinearLayout implements Tunable, Callback {
+public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener {
public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
@@ -152,6 +153,9 @@
if (mHost != null) {
setTiles(mHost.getTiles());
}
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.addCallback(this);
+ }
}
@Override
@@ -163,6 +167,9 @@
for (TileRecord record : mRecords) {
record.tile.removeCallbacks();
}
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.removeCallback(this);
+ }
super.onDetachedFromWindow();
}
@@ -194,12 +201,19 @@
}
public void setBrightnessMirror(BrightnessMirrorController c) {
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.removeCallback(this);
+ }
mBrightnessMirrorController = c;
- ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
- ToggleSliderView mirror = c.getMirror().findViewById(
- R.id.brightness_slider);
- brightnessSlider.setMirror(mirror);
- brightnessSlider.setMirrorController(c);
+ if (mBrightnessMirrorController != null) {
+ mBrightnessMirrorController.addCallback(this);
+ }
+ updateBrightnessMirror();
+ }
+
+ @Override
+ public void onBrightnessMirrorReinflated(View brightnessMirror) {
+ updateBrightnessMirror();
}
View getBrightnessView() {
@@ -246,9 +260,16 @@
super.onConfigurationChanged(newConfig);
mFooter.onConfigurationChanged();
+ updateBrightnessMirror();
+ }
+
+ public void updateBrightnessMirror() {
if (mBrightnessMirrorController != null) {
- // Reload the mirror in case it got reinflated but we didn't.
- setBrightnessMirror(mBrightnessMirrorController);
+ ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
+ ToggleSliderView mirrorSlider = mBrightnessMirrorController.getMirror()
+ .findViewById(R.id.brightness_slider);
+ brightnessSlider.setMirror(mirrorSlider);
+ brightnessSlider.setMirrorController(mBrightnessMirrorController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 14afbfa..12fccda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -83,7 +83,7 @@
@Override
protected void handleClick() {
// Secondary clicks are header clicks, just toggle.
- final boolean isEnabled = (Boolean)mState.value;
+ final boolean isEnabled = mState.value;
mController.setBluetoothEnabled(!isEnabled);
}
@@ -100,6 +100,9 @@
return;
}
showDetail(true);
+ if (!mState.value) {
+ mController.setBluetoothEnabled(true);
+ }
}
@Override
@@ -179,6 +182,7 @@
refreshState();
if (isShowingDetail()) {
mDetailAdapter.updateItems();
+ fireToggleStateChanged(mDetailAdapter.getToggleState());
}
}
@@ -269,7 +273,7 @@
item.icon = R.drawable.ic_qs_bluetooth_on;
item.line1 = device.getName();
item.tag = device;
- int state = mController.getMaxConnectionState(device);
+ int state = device.getMaxConnectionState();
if (state == BluetoothProfile.STATE_CONNECTED) {
item.icon = R.drawable.ic_qs_bluetooth_connected;
int batteryLevel = device.getBatteryLevel();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index f0d7d6c..2fc9fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -34,6 +34,7 @@
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import com.android.internal.app.MediaRouteChooserDialog;
@@ -50,6 +51,7 @@
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -139,25 +141,15 @@
Dependency.get(ActivityStarter.class)
.postStartActivityDismissingKeyguard(getLongClickIntent(), 0);
});
- mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ mDialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+ SystemUIDialog.setShowForAllUsers(mDialog, true);
+ SystemUIDialog.registerDismissListener(mDialog);
+ SystemUIDialog.setWindowOnTop(mDialog);
mUiHandler.post(() -> mDialog.show());
- registerReceiver();
mHost.collapsePanels();
});
}
- private void registerReceiver() {
- mContext.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
- new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
- mRegistered = true;
- mDialog.setOnDismissListener(dialog -> {
- if (mRegistered) {
- mContext.unregisterReceiver(mReceiver);
- mRegistered = false;
- }
- });
- }
-
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_cast_title);
@@ -223,15 +215,6 @@
}
};
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mDialog != null) {
- mDialog.dismiss();
- }
- }
- };
-
private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
private final LinkedHashMap<String, CastDevice> mVisibleOrder = new LinkedHashMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 1e78e65..0e0f949 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -17,6 +17,7 @@
package com.android.systemui.qs.tiles;
import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -27,12 +28,14 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager.LayoutParams;
import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.string;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSIconView;
@@ -111,11 +114,9 @@
protected void handleClick() {
if (mDataController.isMobileDataEnabled()) {
if (mKeyguardMonitor.isSecure() && !mKeyguardMonitor.canSkipBouncer()) {
- mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
- showDisableDialog();
- });
+ mActivityStarter.postQSRunnableDismissingKeyguard(this::showDisableDialog);
} else {
- showDisableDialog();
+ mUiHandler.post(this::showDisableDialog);
}
} else {
mDataController.setMobileDataEnabled(true);
@@ -124,13 +125,18 @@
private void showDisableDialog() {
mHost.collapsePanels();
- SystemUIDialog.applyFlags(new AlertDialog.Builder(mContext)
- .setMessage(R.string.data_usage_disable_mobile)
+ AlertDialog dialog = new Builder(mContext)
+ .setMessage(string.data_usage_disable_mobile)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(
com.android.internal.R.string.alert_windows_notification_turn_off_action,
(d, w) -> mDataController.setMobileDataEnabled(false))
- .create()).show();
+ .create();
+ dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+ SystemUIDialog.setShowForAllUsers(dialog, true);
+ SystemUIDialog.registerDismissListener(dialog);
+ SystemUIDialog.setWindowOnTop(dialog);
+ dialog.show();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 6c31cef..5938749 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -33,6 +33,7 @@
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.quicksettings.Tile;
+import android.util.Log;
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
@@ -54,6 +55,7 @@
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
import com.android.systemui.volume.ZenModePanel;
/** Quick settings tile: Do not disturb **/
@@ -147,7 +149,22 @@
Toast.LENGTH_LONG).show();
return;
}
- showDetail(true);
+ if (!mState.value) {
+ // Because of the complexity of the zen panel, it needs to be shown after
+ // we turn on zen below.
+ mController.addCallback(new ZenModeController.Callback() {
+ @Override
+ public void onZenChanged(int zen) {
+ mController.removeCallback(this);
+ showDetail(true);
+ }
+ });
+ int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN,
+ Global.ZEN_MODE_ALARMS);
+ mController.setZen(zen, null, TAG);
+ } else {
+ showDetail(true);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7391509..136cf21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -127,6 +127,9 @@
return;
}
showDetail(true);
+ if (!mState.value) {
+ mController.setWifiEnabled(true);
+ }
}
@Override
@@ -311,12 +314,10 @@
public View createDetailView(Context context, View convertView, ViewGroup parent) {
if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
mAccessPoints = null;
- mWifiController.scanForAccessPoints();
- fireScanStateChanged(true);
mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
mItems.setTagSuffix("Wifi");
mItems.setCallback(this);
- updateItems();
+ mWifiController.scanForAccessPoints(); // updates APs and items
setItemsVisible(mState.value);
return mItems;
}
@@ -324,9 +325,24 @@
@Override
public void onAccessPointsChanged(final List<AccessPoint> accessPoints) {
mAccessPoints = accessPoints.toArray(new AccessPoint[accessPoints.size()]);
+ filterUnreachableAPs();
+
updateItems();
- if (accessPoints != null && accessPoints.size() > 0) {
- fireScanStateChanged(false);
+ }
+
+ /** Filter unreachable APs from mAccessPoints */
+ private void filterUnreachableAPs() {
+ int numReachable = 0;
+ for (AccessPoint ap : mAccessPoints) {
+ if (ap.isReachable()) numReachable++;
+ }
+ if (numReachable != mAccessPoints.length) {
+ AccessPoint[] unfiltered = mAccessPoints;
+ mAccessPoints = new AccessPoint[numReachable];
+ int i = 0;
+ for (AccessPoint ap : unfiltered) {
+ if (ap.isReachable()) mAccessPoints[i++] = ap;
+ }
}
}
@@ -359,6 +375,12 @@
private void updateItems() {
if (mItems == null) return;
+ if ((mAccessPoints != null && mAccessPoints.length > 0)
+ || !mSignalCallback.mInfo.enabled) {
+ fireScanStateChanged(false);
+ } else {
+ fireScanStateChanged(true);
+ }
// Wi-Fi is off
if (!mSignalCallback.mInfo.enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 1657bfa..d10e080 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -54,6 +54,7 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -613,6 +614,14 @@
}
});
}
+
+ // This will catch the cases when a user launches from recents to another app
+ // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
+ // would not reset the wait for transition flag. This will catch it and make sure that the
+ // flag is reset.
+ if (!event.visible) {
+ mImpl.setWaitingForTransitionStart(false);
+ }
}
/**
@@ -685,6 +694,11 @@
}
}
+ public final void onBusEvent(LaunchTaskFailedEvent event) {
+ // Reset the transition when tasks fail to launch
+ mImpl.setWaitingForTransitionStart(false);
+ }
+
public final void onBusEvent(ConfigurationChangedEvent event) {
// Update the configuration for the Recents component when the activity configuration
// changes as well
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 15b682e..a633a3e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -219,6 +219,7 @@
private boolean mResetToInitialStateWhenResized;
private int mLastWidth;
private int mLastHeight;
+ private boolean mStackActionButtonVisible;
// We keep track of the task view focused by user interaction and draw a frame around it in the
// grid layout.
@@ -287,6 +288,7 @@
mDividerSize = ssp.getDockedDividerSize(context);
mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
mDisplayRect = ssp.getDisplayRect();
+ mStackActionButtonVisible = false;
// Create a frame to draw around the focused task view
if (Recents.getConfiguration().isGridEnabled) {
@@ -975,6 +977,9 @@
mLayoutAlgorithm.clearUnfocusedTaskOverrides();
willScroll = mAnimationHelper.startScrollToFocusedTaskAnimation(newFocusedTask,
requestViewFocus);
+ if (willScroll) {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ }
} else {
// Focus the task view
TaskView newFocusedTaskView = getChildViewForTask(newFocusedTask);
@@ -1159,7 +1164,7 @@
Task focusedTask = getAccessibilityFocusedTask();
info.setScrollable(true);
int focusedTaskIndex = mStack.indexOfStackTask(focusedTask);
- if (focusedTaskIndex > 0) {
+ if (focusedTaskIndex > 0 || !mStackActionButtonVisible) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
if (0 <= focusedTaskIndex && focusedTaskIndex < mStack.getTaskCount() - 1) {
@@ -1812,6 +1817,18 @@
}
}
+ public final void onBusEvent(ShowStackActionButtonEvent event) {
+ if (RecentsDebugFlags.Static.EnableStackActionButton) {
+ mStackActionButtonVisible = true;
+ }
+ }
+
+ public final void onBusEvent(HideStackActionButtonEvent event) {
+ if (RecentsDebugFlags.Static.EnableStackActionButton) {
+ mStackActionButtonVisible = false;
+ }
+ }
+
public final void onBusEvent(LaunchNextTaskRequestEvent event) {
if (!mFinishedLayoutAfterStackReload) {
mLaunchNextAfterFirstMeasure = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 2e10831..bbf9eb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -80,6 +80,7 @@
private static final int MSG_HANDLE_SYSTEM_KEY = 33 << MSG_SHIFT;
private static final int MSG_SHOW_GLOBAL_ACTIONS = 34 << MSG_SHIFT;
private static final int MSG_TOGGLE_PANEL = 35 << MSG_SHIFT;
+ private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -138,6 +139,7 @@
default void handleSystemKey(int arg1) { }
default void handleShowGlobalActionsMenu() { }
+ default void handleShowShutdownUi(boolean isReboot, String reason) { }
}
@VisibleForTesting
@@ -438,6 +440,15 @@
}
}
+ @Override
+ public void showShutdownUi(boolean isReboot, String reason) {
+ synchronized (mLock) {
+ mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI);
+ mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason)
+ .sendToTarget();
+ }
+ }
+
private final class H extends Handler {
private H(Looper l) {
super(l);
@@ -624,6 +635,11 @@
mCallbacks.get(i).handleShowGlobalActionsMenu();
}
break;
+ case MSG_SHOW_SHUTDOWN_UI:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index e5b1afe..68802b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -107,7 +107,6 @@
* Resets the notification entry to be re-used.
*/
public void reset() {
- lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
if (row != null) {
row.reset();
}
@@ -122,6 +121,7 @@
}
public void notifyFullScreenIntentLaunched() {
+ setInterruption();
lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 1889806..5eefe9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -70,6 +70,7 @@
private boolean mHasItemsInStableShelf;
private NotificationIconContainer mCollapsedIcons;
private int mScrollFastThreshold;
+ private int mIconSize;
private int mStatusBarState;
private float mMaxShelfEnd;
private int mRelativeOffset;
@@ -78,6 +79,9 @@
private boolean mNoAnimationsInThisFrame;
private boolean mAnimationsEnabled = true;
private boolean mShowNotificationShelf;
+ private boolean mVibrationOnAnimation;
+ private boolean mUserTouchingScreen;
+ private boolean mTouchActive;
public NotificationShelf(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -94,12 +98,24 @@
setClipChildren(false);
setClipToPadding(false);
mShelfIcons.setShowAllIcons(false);
+ mVibrationOnAnimation = mContext.getResources().getBoolean(
+ R.bool.config_vibrateOnIconAnimation);
+ updateVibrationOnAnimation();
mViewInvertHelper = new ViewInvertHelper(mShelfIcons,
NotificationPanelView.DOZE_ANIMATION_DURATION);
mShelfState = new ShelfState();
initDimens();
}
+ private void updateVibrationOnAnimation() {
+ mShelfIcons.setVibrateOnAnimation(mVibrationOnAnimation && mTouchActive);
+ }
+
+ public void setTouchActive(boolean touchActive) {
+ mTouchActive = touchActive;
+ updateVibrationOnAnimation();
+ }
+
public void bind(AmbientState ambientState, NotificationStackScrollLayout hostLayout) {
mAmbientState = ambientState;
mHostLayout = hostLayout;
@@ -120,6 +136,7 @@
mShelfIcons.setPadding(padding, 0, padding, 0);
mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
+ mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
if (!mShowNotificationShelf) {
setVisibility(GONE);
@@ -486,12 +503,12 @@
}
notificationIconPosition += iconTopPadding;
float shelfIconPosition = getTranslationY() + icon.getTop();
- shelfIconPosition += ((1.0f - icon.getIconScale()) * icon.getHeight()) / 2.0f;
+ shelfIconPosition += (icon.getHeight() - icon.getIconScale() * mIconSize) / 2.0f;
float iconYTranslation = NotificationUtils.interpolate(
notificationIconPosition - shelfIconPosition,
0,
transitionAmount);
- float shelfIconSize = icon.getHeight() * icon.getIconScale();
+ float shelfIconSize = mIconSize * icon.getIconScale();
float alpha = 1.0f;
boolean noIcon = !row.isShowingIcon();
if (noIcon) {
@@ -503,7 +520,7 @@
float newSize = NotificationUtils.interpolate(notificationIconSize, shelfIconSize,
transitionAmount);
if (iconState != null) {
- iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale();
+ iconState.scaleX = newSize / shelfIconSize;
iconState.scaleY = iconState.scaleX;
iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 05d47ec..2cff79d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -23,11 +23,12 @@
import android.app.Notification;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -54,9 +55,16 @@
import com.android.systemui.statusbar.notification.NotificationUtils;
import java.text.NumberFormat;
+import java.util.Arrays;
public class StatusBarIconView extends AnimatedImageView {
public static final int NO_COLOR = 0;
+
+ /**
+ * Multiply alpha values with (1+DARK_ALPHA_BOOST) when dozing. The chosen value boosts
+ * everything above 30% to 50%, making it appear on 1bit color depths.
+ */
+ private static final float DARK_ALPHA_BOOST = 0.67f;
private final int ANIMATION_DURATION_FAST = 100;
public static final int STATE_ICON = 0;
@@ -131,6 +139,9 @@
private final NotificationIconDozeHelper mDozer;
private int mContrastedDrawableColor;
private int mCachedContrastBackgroundColor = NO_COLOR;
+ private float[] mMatrix;
+ private ColorMatrixColorFilter mMatrixColorFilter;
+ private boolean mIsInShelf;
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
this(context, slot, sbn, false);
@@ -544,14 +555,33 @@
private void updateIconColor() {
if (mCurrentSetColor != NO_COLOR) {
- setImageTintList(ColorStateList.valueOf(NotificationUtils.interpolateColors(
- mCurrentSetColor, Color.WHITE, mDarkAmount)));
+ if (mMatrixColorFilter == null) {
+ mMatrix = new float[4 * 5];
+ mMatrixColorFilter = new ColorMatrixColorFilter(mMatrix);
+ }
+ int color = NotificationUtils.interpolateColors(
+ mCurrentSetColor, Color.WHITE, mDarkAmount);
+ updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDarkAmount);
+ mMatrixColorFilter.setColorMatrixArray(mMatrix);
+ setColorFilter(mMatrixColorFilter);
+ invalidate(); // setColorFilter only invalidates if the filter instance changed.
} else {
- setImageTintList(null);
mDozer.updateGrayscale(this, mDarkAmount);
}
}
+ /**
+ * Updates {@param array} such that it represents a matrix that changes RGB to {@param color}
+ * and multiplies the alpha channel with the color's alpha+{@param alphaBoost}.
+ */
+ private static void updateTintMatrix(float[] array, int color, float alphaBoost) {
+ Arrays.fill(array, 0);
+ array[4] = Color.red(color);
+ array[9] = Color.green(color);
+ array[14] = Color.blue(color);
+ array[18] = Color.alpha(color) / 255f + alphaBoost;
+ }
+
public void setIconColor(int iconColor, boolean animate) {
if (mIconColor != iconColor) {
mIconColor = iconColor;
@@ -766,6 +796,14 @@
}
}
+ public void setIsInShelf(boolean isInShelf) {
+ mIsInShelf = isInShelf;
+ }
+
+ public boolean isInShelf() {
+ return mIsInShelf;
+ }
+
public interface OnVisibilityChangedListener {
void onVisibilityChanged(int newVisibility);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 9338887..6060134 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -74,6 +74,15 @@
automaticallySelectUser();
});
+ // Any interaction with the screen should cancel the timer.
+ mContainer.setOnClickListener(v -> {
+ cancelTimer();
+ });
+ mUserGridView.setOnTouchListener((v, e) -> {
+ cancelTimer();
+ return false;
+ });
+
mSwitchingUsers = mParent.findViewById(R.id.switching_users);
}
@@ -152,6 +161,7 @@
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
+ mProgressBar.setProgress(0, true /* animate */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 2dc467f..c45c05e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -23,14 +23,11 @@
import android.content.Context;
import android.os.Handler;
import android.util.Log;
-import android.view.View;
import android.view.animation.Interpolator;
-import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.Interpolators;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
-import com.android.systemui.doze.DozeTriggers;
/**
* Controller which handles all the doze animations of the scrims.
@@ -56,6 +53,8 @@
private boolean mWakeAndUnlocking;
private boolean mFullyPulsing;
+ private float mAodFrontScrimOpacity = 0;
+
public DozeScrimController(ScrimController scrimController, Context context) {
mContext = context;
mScrimController = scrimController;
@@ -70,7 +69,8 @@
mDozingAborted = false;
abortAnimations();
mScrimController.setDozeBehindAlpha(1f);
- mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
+ mScrimController.setDozeInFrontAlpha(
+ mDozeParameters.getAlwaysOn() ? mAodFrontScrimOpacity : 1f);
} else {
cancelPulsing();
if (animate) {
@@ -88,6 +88,19 @@
}
}
+ /**
+ * Set the opacity of the front scrim when showing AOD1
+ *
+ * Used to emulate lower brightness values than the hardware supports natively.
+ */
+ public void setAodDimmingScrim(float scrimOpacity) {
+ mAodFrontScrimOpacity = scrimOpacity;
+ if (mDozing && !isPulsing() && !mDozingAborted && !mWakeAndUnlocking
+ && mDozeParameters.getAlwaysOn()) {
+ mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+ }
+ }
+
public void setWakeAndUnlocking() {
// Immediately abort the doze scrims in case of wake-and-unlock
// for pulsing so the Keyguard fade-out animation scrim can take over.
@@ -126,7 +139,8 @@
if (mDozing && !mWakeAndUnlocking) {
mScrimController.setDozeBehindAlpha(1f);
mScrimController.setDozeInFrontAlpha(
- mDozeParameters.getAlwaysOn() && !mDozingAborted ? 0f : 1f);
+ mDozeParameters.getAlwaysOn() && !mDozingAborted ?
+ mAodFrontScrimOpacity : 1f);
}
}
@@ -322,20 +336,36 @@
mHandler.removeCallbacks(mPulseOutExtended);
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
- startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,
+ startScrimAnimation(true /* inFront */, 1,
mDozeParameters.getPulseOutDuration(),
- Interpolators.ALPHA_IN, mPulseOutFinished);
+ Interpolators.ALPHA_IN, mPulseOutFinishing);
+ }
+ };
+
+ private final Runnable mPulseOutFinishing = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "Pulse out finished");
+ DozeLog.tracePulseFinish();
+ if (mDozeParameters.getAlwaysOn() && mDozing) {
+ // Setting power states can block rendering. For AOD, delay finishing the pulse and
+ // setting the power state until the fully black scrim had time to hit the
+ // framebuffer.
+ mHandler.postDelayed(mPulseOutFinished, 30);
+ } else {
+ mPulseOutFinished.run();
+ }
}
};
private final Runnable mPulseOutFinished = new Runnable() {
@Override
public void run() {
- if (DEBUG) Log.d(TAG, "Pulse out finished");
- DozeLog.tracePulseFinish();
-
// Signal that the pulse is all finished so we can turn the screen off now.
- pulseFinished();
+ DozeScrimController.this.pulseFinished();
+ if (mDozeParameters.getAlwaysOn()) {
+ mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+ }
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 02202cf..cb96dea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -29,6 +29,7 @@
import com.android.keyguard.LatencyTracker;
import com.android.systemui.Dependency;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
/**
@@ -101,6 +102,7 @@
private final Context mContext;
private int mPendingAuthenticatedUserId = -1;
private boolean mPendingShowBouncer;
+ private boolean mHasScreenTurnedOnSinceAuthenticating;
public FingerprintUnlockController(Context context,
DozeScrimController dozeScrimController,
@@ -113,6 +115,7 @@
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
mUpdateMonitor.registerCallback(this);
Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
+ Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
mDozeScrimController = dozeScrimController;
mKeyguardViewMediator = keyguardViewMediator;
@@ -184,8 +187,13 @@
Trace.endSection();
return;
}
+ startWakeAndUnlock(calculateMode());
+ }
+
+ public void startWakeAndUnlock(int mode) {
boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
- mMode = calculateMode();
+ mMode = mode;
+ mHasScreenTurnedOnSinceAuthenticating = false;
if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
// If we are waking the device up while we are pulsing the clock and the
// notifications would light up first, creating an unpleasant animation.
@@ -228,6 +236,7 @@
true /* allowEnterAnimation */);
} else {
Trace.beginSection("MODE_WAKE_AND_UNLOCK");
+
mDozeScrimController.abortDoze();
}
mStatusBarWindowManager.setStatusBarFocusable(false);
@@ -354,4 +363,16 @@
}
}
};
+
+ private final ScreenLifecycle.Observer mScreenObserver =
+ new ScreenLifecycle.Observer() {
+ @Override
+ public void onScreenTurnedOn() {
+ mHasScreenTurnedOnSinceAuthenticating = true;
+ }
+ };
+
+ public boolean hasScreenTurnedOnSinceAuthenticating() {
+ return mHasScreenTurnedOnSinceAuthenticating;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index cdba24c..6cfa838 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -332,6 +332,7 @@
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
mLockIcon.setLayoutParams(lp);
+ mLockIcon.setContentDescription(getContext().getText(R.string.accessibility_unlock_button));
mLockIcon.update(true /* force */);
lp = mLeftAffordanceView.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 95f32bb..fd95cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -234,8 +234,11 @@
}
protected void ensureView() {
- mHandler.removeCallbacks(mRemoveViewRunnable);
- if (mRoot == null) {
+ // Removal of the view might be deferred to reduce unlock latency,
+ // in this case we need to force the removal, otherwise we'll
+ // end up in an unpredictable state.
+ boolean forceRemoval = mHandler.hasCallbacks(mRemoveViewRunnable);
+ if (mRoot == null || forceRemoval) {
inflateView();
}
}
@@ -249,6 +252,7 @@
mKeyguardView.setViewMediatorCallback(mCallback);
mContainer.addView(mRoot, mContainer.getChildCount());
mRoot.setVisibility(View.INVISIBLE);
+ mRoot.dispatchApplyWindowInsets(mRoot.getRootWindowInsets());
}
protected void removeView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 881de67..a6691b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -50,6 +50,7 @@
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
@@ -346,6 +347,9 @@
applyDarkness(R.id.signal_cluster, tintArea, intensity, iconColor);
applyDarkness(R.id.battery, tintArea, intensity, iconColor);
applyDarkness(R.id.clock, tintArea, intensity, iconColor);
+ // Reload user avatar
+ ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
+ .onDensityOrFontScaleChanged();
}
private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index bccc5d5..c241290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -178,7 +178,7 @@
: 0);
setRestingAlpha(
anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
- setImageDrawable(icon);
+ setImageDrawable(icon, false);
mHasFingerPrintIcon = anyFingerprintIcon;
if (animation != null && isAnim) {
animation.forceAnimationOnUI();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index c487901..87f5ca7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -158,7 +158,7 @@
}
@Override
- public void onWallpaperColorsChanged(WallpaperColors colors, int which) {
+ public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 7b2a5f0..57c8827 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -59,6 +59,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.function.Consumer;
public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
final static boolean DEBUG = false;
@@ -563,10 +564,7 @@
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
- DockedStackExistsListener.register(exists -> mHandler.post(() -> {
- mDockedStackExists = exists;
- updateRecentsIcon();
- }));
+ DockedStackExistsListener.register(mDockedListener);
updateRotatedViews();
}
@@ -575,15 +573,16 @@
mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
mRotatedViews[Surface.ROTATION_270] =
mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
+
+ updateCurrentView();
}
public boolean needsReorient(int rotation) {
return mCurrentRotation != rotation;
}
- private boolean updateCurrentView() {
+ private void updateCurrentView() {
final int rot = mDisplay.getRotation();
- if (rot == mCurrentRotation) return false;
for (int i=0; i<4; i++) {
mRotatedViews[i].setVisibility(View.GONE);
}
@@ -595,7 +594,6 @@
}
updateLayoutTransitionsEnabled();
mCurrentRotation = rot;
- return true;
}
private void updateRecentsIcon() {
@@ -608,14 +606,11 @@
}
public void reorient() {
- if (!updateCurrentView()) {
- return;
- }
+ updateCurrentView();
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
-
mDeadZone.setDisplayRotation(mCurrentRotation);
// force the low profile & disabled states into compliance
@@ -649,7 +644,6 @@
mVertical = newVertical;
//Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
reorient();
- getHomeButton().setVertical(mVertical);
notifyVerticalChangedListener(newVertical);
}
@@ -839,4 +833,8 @@
void onVerticalChanged(boolean isVertical);
}
+ private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+ mDockedStackExists = exists;
+ updateRecentsIcon();
+ });
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
new file mode 100644
index 0000000..004a604
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
@@ -0,0 +1,115 @@
+/*
+ * 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.statusbar.phone;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+/**
+ * Redirects touches that aren't handled by any child view to the nearest
+ * clickable child. Only takes effect on <sw600dp.
+ */
+public class NearestTouchFrame extends FrameLayout {
+
+ private final ArrayList<View> mClickableChildren = new ArrayList<>();
+ private final boolean mIsActive;
+ private final int[] mTmpInt = new int[2];
+ private final int[] mOffset = new int[2];
+ private View mTouchingChild;
+
+ public NearestTouchFrame(Context context, AttributeSet attrs) {
+ this(context, attrs, context.getResources().getConfiguration());
+ }
+
+ @VisibleForTesting
+ NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
+ super(context, attrs);
+ mIsActive = c.smallestScreenWidthDp < 600;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mClickableChildren.clear();
+ addClickableChildren(this);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ getLocationInWindow(mOffset);
+ }
+
+ private void addClickableChildren(ViewGroup group) {
+ final int N = group.getChildCount();
+ for (int i = 0; i < N; i++) {
+ View child = group.getChildAt(i);
+ if (child.isClickable()) {
+ mClickableChildren.add(child);
+ } else if (child instanceof ViewGroup) {
+ addClickableChildren((ViewGroup) child);
+ }
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mIsActive) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ mTouchingChild = findNearestChild(event);
+ }
+ if (mTouchingChild != null) {
+ event.offsetLocation(mTouchingChild.getWidth() / 2 - event.getX(),
+ mTouchingChild.getHeight() / 2 - event.getY());
+ return mTouchingChild.dispatchTouchEvent(event);
+ }
+ }
+ return super.onTouchEvent(event);
+ }
+
+ private View findNearestChild(MotionEvent event) {
+ return mClickableChildren.stream().map(v -> new Pair<>(distance(v, event), v))
+ .min(Comparator.comparingInt(f -> f.first)).get().second;
+ }
+
+ private int distance(View v, MotionEvent event) {
+ v.getLocationInWindow(mTmpInt);
+ int left = mTmpInt[0] - mOffset[0];
+ int top = mTmpInt[1] - mOffset[1];
+ int right = left + v.getWidth();
+ int bottom = top + v.getHeight();
+
+ int x = Math.min(Math.abs(left - (int) event.getX()),
+ Math.abs((int) event.getX() - right));
+ int y = Math.min(Math.abs(top - (int) event.getY()),
+ Math.abs((int) event.getY() - bottom));
+
+ return Math.max(x, y);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 38c8d31..e0d9748 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -22,6 +22,8 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Icon;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
import android.support.v4.util.ArrayMap;
import android.support.v4.util.ArraySet;
import android.util.AttributeSet;
@@ -122,6 +124,8 @@
private float mVisualOverflowAdaption;
private boolean mDisallowNextAnimation;
private boolean mAnimationsEnabled = true;
+ private boolean mVibrateOnAnimation;
+ private Vibrator mVibrator;
private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
private int mDarkOffsetX;
@@ -129,6 +133,7 @@
super(context, attrs);
initDimens();
setWillNotDraw(!DEBUG);
+ mVibrator = mContext.getSystemService(Vibrator.class);
}
private void initDimens() {
@@ -499,6 +504,10 @@
return width - (getWidth() - getActualPaddingStart() - getActualPaddingEnd()) > 0;
}
+ public void setVibrateOnAnimation(boolean vibrateOnAnimation) {
+ mVibrateOnAnimation = vibrateOnAnimation;
+ }
+
public int getIconSize() {
return mIconSize;
}
@@ -611,6 +620,13 @@
} else {
super.applyToView(view);
}
+ boolean wasInShelf = icon.isInShelf();
+ boolean inShelf = iconAppearAmount == 1.0f;
+ icon.setIsInShelf(inShelf);
+ if (mVibrateOnAnimation && !justAdded && mAnimationsEnabled
+ && wasInShelf != inShelf) {
+ mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_TICK));
+ }
}
justAdded = false;
justReplaced = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 4ffc15f..04be357 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -231,6 +231,7 @@
private int mAmbientIndicationBottomPadding;
private boolean mIsFullWidth;
private float mDarkAmount;
+ private float mDarkAmountTarget;
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mNoVisibleNotifications = true;
private ValueAnimator mDarkAnimator;
@@ -2578,8 +2579,13 @@
return;
}
if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
- mDarkAnimator.cancel();
+ if (animate && mDarkAmountTarget == darkAmount) {
+ return;
+ } else {
+ mDarkAnimator.cancel();
+ }
}
+ mDarkAmountTarget = darkAmount;
if (animate) {
mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
mDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 16d85be..d3ee550 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -24,6 +24,8 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.SystemClock;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.InputDevice;
@@ -98,6 +100,7 @@
private FlingAnimationUtils mFlingAnimationUtilsClosing;
private FlingAnimationUtils mFlingAnimationUtilsDismissing;
private FalsingManager mFalsingManager;
+ private final Vibrator mVibrator;
/**
* Whether an instant expand request is currently pending and we are just waiting for layout.
@@ -199,6 +202,7 @@
mFalsingManager = FalsingManager.getInstance(context);
mNotificationsDragEnabled =
getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
+ mVibrator = mContext.getSystemService(Vibrator.class);
}
protected void loadDimens() {
@@ -390,6 +394,7 @@
runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
false /* collapseWhenFinished */);
notifyBarPanelExpansionChanged();
+ mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
}
protected abstract float getOpeningHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 6cdb757..4ae1393 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -196,8 +196,7 @@
}
// TTY status
- mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
- mIconController.setIconVisibility(mSlotTty, false);
+ updateTTY();
// bluetooth status
updateBluetooth();
@@ -419,9 +418,17 @@
mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
}
- private final void updateTTY(Intent intent) {
- int currentTtyMode = intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
- TelecomManager.TTY_MODE_OFF);
+ private final void updateTTY() {
+ TelecomManager telecomManager =
+ (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+ if (telecomManager == null) {
+ updateTTY(TelecomManager.TTY_MODE_OFF);
+ } else {
+ updateTTY(telecomManager.getCurrentTtyMode());
+ }
+ }
+
+ private final void updateTTY(int currentTtyMode) {
boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
@@ -755,7 +762,8 @@
} else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
updateSimState(intent);
} else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
- updateTTY(intent);
+ updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
+ TelecomManager.TTY_MODE_OFF));
} else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
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 62d4b73..1d64480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -25,6 +25,7 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Trace;
import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -36,6 +37,7 @@
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
+import com.android.internal.graphics.ColorUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -46,6 +48,8 @@
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.ViewState;
+import java.util.function.Consumer;
+
/**
* Controls both the scrim behind the notifications and in front of the notifications (when a
* security method gets shown).
@@ -85,6 +89,7 @@
private boolean mNeedsDrawableColorUpdate;
protected float mScrimBehindAlpha;
+ protected float mScrimBehindAlphaResValue;
protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
@@ -125,17 +130,24 @@
private boolean mWakingUpFromAodInProgress;
/** Wake up from AOD transition is animating; need to reset when animation finishes */
private boolean mWakingUpFromAodAnimationRunning;
+ private boolean mScrimsVisble;
+ private final Consumer<Boolean> mScrimVisibleListener;
public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
- ScrimView scrimInFront, View headsUpScrim) {
+ ScrimView scrimInFront, View headsUpScrim,
+ Consumer<Boolean> scrimVisibleListener) {
mScrimBehind = scrimBehind;
mScrimInFront = scrimInFront;
mHeadsUpScrim = headsUpScrim;
+ mScrimVisibleListener = scrimVisibleListener;
final Context context = scrimBehind.getContext();
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
mLightBarController = lightBarController;
- mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ mScrimBehindAlphaResValue = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ // 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.
+ mScrimBehindAlpha = mScrimBehindAlphaResValue;
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
@@ -192,7 +204,11 @@
scheduleUpdate();
}
+ /** Prepares the wakeUpFromAod animation (while turning on screen); Forces black scrims. */
public void prepareWakeUpFromAod() {
+ if (mWakingUpFromAodInProgress) {
+ return;
+ }
mWakingUpFromAodInProgress = true;
mWakingUpFromAodStarting = true;
mAnimateChange = false;
@@ -200,10 +216,12 @@
onPreDraw();
}
+ /** Starts the wakeUpFromAod animation (once screen is on); animate to transparent scrims. */
public void wakeUpFromAod() {
if (mWakeAndUnlocking || mAnimateKeyguardFadingOut) {
// Wake and unlocking has a separate transition that must not be interfered with.
mWakingUpFromAodStarting = false;
+ mWakingUpFromAodInProgress = false;
return;
}
if (mWakingUpFromAodStarting) {
@@ -218,6 +236,7 @@
mWakeAndUnlocking = true;
mAnimatingDozeUnlock = true;
mWakingUpFromAodStarting = false;
+ mWakingUpFromAodInProgress = false;
scheduleUpdate();
}
@@ -328,21 +347,30 @@
}
protected void updateScrims() {
-
- // Make sure we have the right gradients
+ // Make sure we have the right gradients and their opacities will satisfy GAR.
if (mNeedsDrawableColorUpdate) {
mNeedsDrawableColorUpdate = false;
+ final GradientColors currentScrimColors;
if (mKeyguardShowing) {
// Always animate color changes if we're seeing the keyguard
mScrimInFront.setColors(mLockColors, true /* animated */);
mScrimBehind.setColors(mLockColors, true /* animated */);
+ currentScrimColors = mLockColors;
} else {
// Only animate scrim color if the scrim view is actually visible
boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
mScrimInFront.setColors(mSystemColors, animateScrimInFront);
mScrimBehind.setColors(mSystemColors, animateScrimBehind);
+ currentScrimColors = mSystemColors;
}
+
+ // Calculate minimum scrim opacity for white or black text.
+ int textColor = currentScrimColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
+ int mainColor = currentScrimColors.getMainColor();
+ float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
+ 4.5f /* minimumContrast */) / 255f;
+ mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
mLightBarController.setScrimColor(mScrimInFront.getColors());
}
@@ -351,7 +379,8 @@
setScrimBehindAlpha(0f);
} else if (mWakeAndUnlocking) {
// During wake and unlock, we first hide everything behind a black scrim, which then
- // gets faded out from animateKeyguardFadingOut.
+ // gets faded out from animateKeyguardFadingOut. This must never be animated.
+ mAnimateChange = false;
if (mDozing) {
setScrimInFrontAlpha(0f);
setScrimBehindAlpha(1f);
@@ -359,13 +388,24 @@
setScrimInFrontAlpha(1f);
setScrimBehindAlpha(0f);
}
- } else if (!mKeyguardShowing && !mBouncerShowing) {
+ } else if (!mKeyguardShowing && !mBouncerShowing && !mWakingUpFromAodStarting) {
updateScrimNormal();
setScrimInFrontAlpha(0);
} else {
updateScrimKeyguard();
}
mAnimateChange = false;
+ dispatchScrimsVisible();
+ }
+
+ private void dispatchScrimsVisible() {
+ boolean scrimsVisible = mScrimBehind.getViewAlpha() > 0 || mScrimInFront.getViewAlpha() > 0;
+
+ if (mScrimsVisble != scrimsVisible) {
+ mScrimsVisble = scrimsVisible;
+
+ mScrimVisibleListener.accept(scrimsVisible);
+ }
}
private void updateScrimKeyguard() {
@@ -457,6 +497,10 @@
alpha = Math.max(0, Math.min(1.0f, alpha));
scrimView.setViewAlpha(alpha);
+ Trace.traceCounter(Trace.TRACE_TAG_APP,
+ scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
+ (int) (alpha * 255));
+
int dozeTint = Color.TRANSPARENT;
boolean dozing = mAnimatingDozeUnlock || mDozing;
@@ -464,10 +508,15 @@
if (dozing || frontScrimDozing && scrim == mScrimInFront) {
dozeTint = Color.BLACK;
}
+ Trace.traceCounter(Trace.TRACE_TAG_APP,
+ scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
+ dozeTint == Color.BLACK ? 1 : 0);
+
scrimView.setTint(dozeTint);
} else {
scrim.setAlpha(alpha1);
}
+ dispatchScrimsVisible();
}
private void startScrimAnimation(final View scrim, float target) {
@@ -477,6 +526,7 @@
float alpha = (float) animation.getAnimatedValue();
setCurrentScrimAlpha(scrim, alpha);
updateScrimColor(scrim);
+ dispatchScrimsVisible();
});
anim.setInterpolator(getInterpolator());
anim.setStartDelay(mAnimationDelay);
@@ -493,12 +543,13 @@
mKeyguardFadingOutInProgress = false;
mAnimatingDozeUnlock = false;
}
- if (mWakingUpFromAodAnimationRunning) {
+ if (mWakingUpFromAodAnimationRunning && !mDeferFinishedListener) {
mWakingUpFromAodAnimationRunning = false;
mWakingUpFromAodInProgress = false;
}
scrim.setTag(TAG_KEY_ANIM, null);
scrim.setTag(TAG_KEY_ANIM_TARGET, null);
+ dispatchScrimsVisible();
}
});
anim.start();
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 8fc2153..59e7005 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -119,6 +119,7 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.Display;
+import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -141,6 +142,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.logging.MetricsLogger;
@@ -748,7 +750,7 @@
private SysuiColorExtractor mColorExtractor;
private ForegroundServiceController mForegroundServiceController;
private ScreenLifecycle mScreenLifecycle;
- private WakefulnessLifecycle mWakefulnessLifecycle;
+ @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle;
private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
final int N = array.size();
@@ -1132,7 +1134,12 @@
ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
- scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
+ scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
+ scrimsVisible -> {
+ if (mStatusBarWindowManager != null) {
+ mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
+ }
+ });
if (mScrimSrcModeEnabled) {
Runnable runnable = new Runnable() {
@Override
@@ -3519,6 +3526,14 @@
pw.print (" ");
mStackScroller.dump(fd, pw, args);
}
+ pw.println(" Theme:");
+ if (mOverlayManager == null) {
+ pw.println(" overlay manager not initialized!");
+ } else {
+ pw.println(" dark overlay on: " + isUsingDarkTheme());
+ }
+ final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
+ pw.println(" light wallpaper theme: " + lightWpTheme);
DozeLog.dump(pw);
@@ -3722,7 +3737,6 @@
}
}
else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- notifyHeadsUpScreenOff();
finishBarAnimations();
resetUserExpandedStates();
}
@@ -3774,6 +3788,15 @@
private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
boolean afterKeyguardGone) {
+ if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+ && mUnlockMethodCache.canSkipBouncer()
+ && !mLeaveOpenOnKeyguardHide
+ && isPulsing()) {
+ // Reuse the fingerprint wake-and-unlock transition if we dismiss keyguard from a pulse.
+ // TODO: Factor this transition out of FingerprintUnlockController.
+ mFingerprintUnlockController.startWakeAndUnlock(
+ FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
+ }
if (mStatusBarKeyguardViewManager.isShowing()) {
mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
afterKeyguardGone);
@@ -4210,7 +4233,10 @@
public void showKeyguard() {
mKeyguardRequested = true;
+ mLeaveOpenOnKeyguardHide = false;
+ mPendingRemoteInputView = null;
updateIsKeyguard();
+ mAssistManager.onLockscreenShown();
}
public boolean hideKeyguard() {
@@ -4259,14 +4285,11 @@
}
updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
updatePanelExpansionForKeyguard();
- mLeaveOpenOnKeyguardHide = false;
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
mDraggedDownRow = null;
}
- mPendingRemoteInputView = null;
- mAssistManager.onLockscreenShown();
}
private void updatePanelExpansionForKeyguard() {
@@ -4406,15 +4429,19 @@
setBarState(StatusBarState.SHADE);
View viewToClick = null;
if (mLeaveOpenOnKeyguardHide) {
- mLeaveOpenOnKeyguardHide = false;
+ if (!mKeyguardRequested) {
+ mLeaveOpenOnKeyguardHide = false;
+ }
long delay = calculateGoingToFullShadeDelay();
mNotificationPanel.animateToFullShade(delay);
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
mDraggedDownRow = null;
}
- viewToClick = mPendingRemoteInputView;
- mPendingRemoteInputView = null;
+ if (!mKeyguardRequested) {
+ viewToClick = mPendingRemoteInputView;
+ mPendingRemoteInputView = null;
+ }
// Disable layout transitions in navbar for this transition because the load is just
// too heavy for the CPU and GPU on any device.
@@ -4622,6 +4649,7 @@
}
private void updateDozingState() {
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
Trace.beginSection("StatusBar#updateDozingState");
boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
mNotificationPanel.setDozing(mDozing, animate);
@@ -4725,6 +4753,7 @@
// Make our window larger and the panel expanded.
makeExpandedVisible(true);
mNotificationPanel.expand(false /* animate */);
+ recomputeDisableFlags(false /* animate */);
}
private void instantCollapseNotificationPanel() {
@@ -5162,6 +5191,7 @@
@Override
public void onStartedGoingToSleep() {
+ notifyHeadsUpGoingToSleep();
dismissVolumeDialog();
}
@@ -5171,6 +5201,9 @@
mStackScroller.setAnimationsEnabled(true);
mVisualStabilityManager.setScreenOn(true);
mNotificationPanel.setTouchDisabled(false);
+
+ maybePrepareWakeUpFromAod();
+
mDozeServiceHost.stopDozing();
updateVisibleToUser();
updateIsKeyguard();
@@ -5183,11 +5216,7 @@
mFalsingManager.onScreenTurningOn();
mNotificationPanel.onScreenTurningOn();
- int wakefulness = mWakefulnessLifecycle.getWakefulness();
- if (mDozing && (wakefulness == WAKEFULNESS_WAKING
- || wakefulness == WAKEFULNESS_ASLEEP) && !isPulsing()) {
- mScrimController.prepareWakeUpFromAod();
- }
+ maybePrepareWakeUpFromAod();
if (mLaunchCameraOnScreenTurningOn) {
mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
@@ -5216,6 +5245,14 @@
return mWakefulnessLifecycle.getWakefulness();
}
+ private void maybePrepareWakeUpFromAod() {
+ int wakefulness = mWakefulnessLifecycle.getWakefulness();
+ if (mDozing && (wakefulness == WAKEFULNESS_WAKING
+ || wakefulness == WAKEFULNESS_ASLEEP) && !isPulsing()) {
+ mScrimController.prepareWakeUpFromAod();
+ }
+ }
+
private void vibrateForCameraGesture() {
// Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
@@ -5372,6 +5409,7 @@
private final class DozeServiceHost implements DozeHost {
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private boolean mAnimateWakeup;
+ private boolean mIgnoreTouchWhilePulsing;
@Override
public String toString() {
@@ -5442,6 +5480,7 @@
mStackScroller.setPulsing(pulsing);
mNotificationPanel.setPulsing(pulsing != null);
mVisualStabilityManager.setPulsing(pulsing != null);
+ mIgnoreTouchWhilePulsing = false;
}
}, reason);
}
@@ -5456,6 +5495,17 @@
}
@Override
+ public void onIgnoreTouchWhilePulsing(boolean ignore) {
+ if (ignore != mIgnoreTouchWhilePulsing) {
+ DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
+ }
+ mIgnoreTouchWhilePulsing = ignore;
+ if (isDozing() && ignore) {
+ mStatusBarWindow.cancelCurrentTouch();
+ }
+ }
+
+ @Override
public void dozeTimeTick() {
mNotificationPanel.refreshTime();
}
@@ -5503,6 +5553,11 @@
@Override
public void setAnimateWakeup(boolean animateWakeup) {
+ if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
+ || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING) {
+ // Too late to change the wakeup animation.
+ return;
+ }
mAnimateWakeup = animateWakeup;
}
@@ -5525,6 +5580,11 @@
mStatusBarWindowManager.setDozeScreenBrightness(value);
}
+ @Override
+ public void setAodDimmingScrim(float scrimOpacity) {
+ mDozeScrimController.setAodDimmingScrim(scrimOpacity);
+ }
+
public void dispatchDoubleTap(float viewX, float viewY) {
dispatchTap(mAmbientIndicationContainer, viewX, viewY);
dispatchTap(mAmbientIndicationContainer, viewX, viewY);
@@ -5547,6 +5607,10 @@
}
}
+ public boolean shouldIgnoreTouch() {
+ return isDozing() && mDozeServiceHost.mIgnoreTouchWhilePulsing;
+ }
+
// Begin Extra BaseStatusBar methods.
protected CommandQueue mCommandQueue;
@@ -5733,15 +5797,18 @@
boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
// close the shade if it was open
- if (handled) {
+ if (handled && !mNotificationPanel.isFullyCollapsed()) {
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
true /* force */);
visibilityChanged(false);
mAssistManager.hideAssist();
+
+ // Wait for activity start.
+ return true;
+ } else {
+ return false;
}
- // Wait for activity start.
- return handled;
}
}, afterKeyguardGone);
return true;
@@ -6358,6 +6425,7 @@
if (row.isDark()) {
return false;
}
+ v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (row.areGutsExposed()) {
closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
true /* removeControls */, -1 /* x */, -1 /* y */,
@@ -6790,12 +6858,16 @@
}
}.start();
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
+ if (!mNotificationPanel.isFullyCollapsed()) {
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */, true /* delayed */);
+ visibilityChanged(false);
- return true;
+ return true;
+ } else {
+ return false;
+ }
}
}, afterKeyguardGone);
}
@@ -6947,12 +7019,16 @@
new Thread(runnable).start();
}
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
+ if (!mNotificationPanel.isFullyCollapsed()) {
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */, true /* delayed */);
+ visibilityChanged(false);
- return true;
+ return true;
+ } else {
+ return false;
+ }
}
}, afterKeyguardGone);
}
@@ -7249,7 +7325,7 @@
setAreThereNotifications();
}
- protected void notifyHeadsUpScreenOff() {
+ protected void notifyHeadsUpGoingToSleep() {
maybeEscalateHeadsUp();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 252df17..b4b859c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -71,6 +71,7 @@
protected final Context mContext;
private final StatusBarWindowManager mStatusBarWindowManager;
+ private final boolean mDisplayBlanksAfterDoze;
protected LockPatternUtils mLockPatternUtils;
protected ViewMediatorCallback mViewMediatorCallback;
@@ -101,6 +102,9 @@
private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
private boolean mDeferScrimFadeOut;
+ // Dismiss action to be launched when we stop dozing or the keyguard is gone.
+ private DismissWithActionRequest mPendingWakeupAction;
+
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -109,7 +113,7 @@
// Since we won't get a setOccluded call we have to reset the view manually such that
// the bouncer goes away.
if (mOccluded) {
- reset(false /* hideBouncerWhenShowing */);
+ reset(true /* hideBouncerWhenShowing */);
}
}
};
@@ -121,6 +125,8 @@
mLockPatternUtils = lockPatternUtils;
mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
+ mDisplayBlanksAfterDoze = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_displayBlanksAfterDoze);
}
public void registerStatusBar(StatusBar statusBar,
@@ -153,17 +159,22 @@
*/
protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
if (mBouncer.needsFullscreenBouncer() && !mDozing) {
-
// The keyguard might be showing (already). So we need to hide it.
mStatusBar.hideKeyguard();
mBouncer.show(true /* resetSecuritySelection */);
} else {
mStatusBar.showKeyguard();
if (hideBouncerWhenShowing) {
- mBouncer.hide(false /* destroyView */);
+ hideBouncer(false /* destroyView */);
mBouncer.prepare();
}
}
+ updateStates();
+ }
+
+ private void hideBouncer(boolean destroyView) {
+ mBouncer.hide(destroyView);
+ cancelPendingWakeupAction();
}
private void showBouncer() {
@@ -176,6 +187,15 @@
public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
boolean afterKeyguardGone) {
if (mShowing) {
+ cancelPendingWakeupAction();
+ // If we're dozing, this needs to be delayed until after we wake up - unless we're
+ // wake-and-unlocking, because there dozing will last until the end of the transition.
+ if (mDozing && !isWakeAndUnlocking()) {
+ mPendingWakeupAction = new DismissWithActionRequest(
+ r, cancelAction, afterKeyguardGone);
+ return;
+ }
+
if (!afterKeyguardGone) {
mBouncer.showWithDismissAction(r, cancelAction);
} else {
@@ -186,6 +206,11 @@
updateStates();
}
+ private boolean isWakeAndUnlocking() {
+ int mode = mFingerprintUnlockController.getMode();
+ return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
+ }
+
/**
* Adds a {@param runnable} to be executed after Keyguard is gone.
*/
@@ -198,10 +223,12 @@
*/
public void reset(boolean hideBouncerWhenShowing) {
if (mShowing) {
- if (mOccluded) {
+ if (mOccluded && !mDozing) {
mStatusBar.hideKeyguard();
mStatusBar.stopWaitingForKeyguardExit();
- mBouncer.hide(false /* destroyView */);
+ if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
+ hideBouncer(false /* destroyView */);
+ }
} else {
showBouncerOrKeyguard(hideBouncerWhenShowing);
}
@@ -247,8 +274,14 @@
public void setDozing(boolean dozing) {
if (mDozing != dozing) {
mDozing = dozing;
- reset(dozing /* hideBouncerWhenShowing */);
+ if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
+ reset(dozing /* hideBouncerWhenShowing */);
+ }
updateStates();
+
+ if (!dozing) {
+ launchPendingWakeupAction();
+ }
}
}
@@ -283,15 +316,19 @@
return;
}
}
+ boolean isOccluding = !mOccluded && occluded;
mOccluded = occluded;
if (mShowing) {
mStatusBar.updateMediaMetaData(false, animate && !occluded);
}
mStatusBarWindowManager.setKeyguardOccluded(occluded);
- // If Keyguard is reshown, don't hide the bouncer as it might just have been requested by
- // a FLAG_DISMISS_KEYGUARD_ACTIVITY.
- reset(false /* hideBouncerWhenShowing*/);
+ // setDozing(false) will call reset once we stop dozing.
+ if (!mDozing) {
+ // If Keyguard is reshown, don't hide the bouncer as it might just have been requested
+ // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
+ reset(isOccluding /* hideBouncerWhenShowing*/);
+ }
if (animate && !occluded && mShowing) {
mStatusBar.animateKeyguardUnoccluding();
}
@@ -321,6 +358,7 @@
*/
public void hide(long startTime, long fadeoutDuration) {
mShowing = false;
+ launchPendingWakeupAction();
if (KeyguardUpdateMonitor.getInstance(mContext).needsSlowUnlockTransition()) {
fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
@@ -334,7 +372,7 @@
public void run() {
mStatusBarWindowManager.setKeyguardShowing(false);
mStatusBarWindowManager.setKeyguardFadingAway(true);
- mBouncer.hide(true /* destroyView */);
+ hideBouncer(true /* destroyView */);
updateStates();
mScrimController.animateKeyguardFadingOut(
StatusBar.FADE_KEYGUARD_START_DELAY,
@@ -360,7 +398,7 @@
}
mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
mFingerprintUnlockController.startKeyguardFadingAway();
- mBouncer.hide(true /* destroyView */);
+ hideBouncer(true /* destroyView */);
if (wakeUnlockPulsing) {
mStatusBarWindowManager.setKeyguardFadingAway(true);
mStatusBar.fadeKeyguardWhilePulsing();
@@ -373,7 +411,11 @@
if (!staying) {
mStatusBarWindowManager.setKeyguardFadingAway(true);
if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) {
- if (!mScreenTurnedOn) {
+ boolean turnedOnSinceAuth =
+ mFingerprintUnlockController.hasScreenTurnedOnSinceAuthenticating();
+ if (!mScreenTurnedOn || mDisplayBlanksAfterDoze && !turnedOnSinceAuth) {
+ // Not ready to animate yet; either because the screen is not on yet,
+ // or it is on but will turn off before waking out of doze.
mDeferScrimFadeOut = true;
} else {
@@ -399,11 +441,12 @@
}
public void onDensityOrFontScaleChanged() {
- mBouncer.hide(true /* destroyView */);
+ hideBouncer(true /* destroyView */);
}
public void onOverlayChanged() {
- mBouncer.hide(true /* destroyView */);
+ hideBouncer(true /* destroyView */);
+ mBouncer.prepare();
}
private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
@@ -642,4 +685,38 @@
public ViewRootImpl getViewRootImpl() {
return mStatusBar.getStatusBarView().getViewRootImpl();
}
+
+ public void launchPendingWakeupAction() {
+ DismissWithActionRequest request = mPendingWakeupAction;
+ mPendingWakeupAction = null;
+ if (request != null) {
+ if (mShowing) {
+ dismissWithAction(request.dismissAction, request.cancelAction,
+ request.afterKeyguardGone);
+ } else if (request.dismissAction != null) {
+ request.dismissAction.onDismiss();
+ }
+ }
+ }
+
+ public void cancelPendingWakeupAction() {
+ DismissWithActionRequest request = mPendingWakeupAction;
+ mPendingWakeupAction = null;
+ if (request != null && request.cancelAction != null) {
+ request.cancelAction.run();
+ }
+ }
+
+ private static class DismissWithActionRequest {
+ final OnDismissAction dismissAction;
+ final Runnable cancelAction;
+ final boolean afterKeyguardGone;
+
+ DismissWithActionRequest(OnDismissAction dismissAction, Runnable cancelAction,
+ boolean afterKeyguardGone) {
+ this.dismissAction = dismissAction;
+ this.cancelAction = cancelAction;
+ this.afterKeyguardGone = afterKeyguardGone;
+ }
+ }
}
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 debba49..eaa6a33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -185,7 +185,7 @@
private boolean isExpanded(State state) {
return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
|| state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
- || state.headsUpShowing);
+ || state.headsUpShowing || state.scrimsVisible);
}
private void applyFitsSystemWindows(State state) {
@@ -324,6 +324,11 @@
apply(mCurrentState);
}
+ public void setScrimsVisible(boolean scrimsVisible) {
+ mCurrentState.scrimsVisible = scrimsVisible;
+ apply(mCurrentState);
+ }
+
public void setHeadsUpShowing(boolean showing) {
mCurrentState.headsUpShowing = showing;
apply(mCurrentState);
@@ -425,6 +430,7 @@
boolean remoteInputActive;
boolean forcePluginOpen;
boolean dozing;
+ boolean scrimsVisible;
private boolean isKeyguardShowingAndNotOccluded() {
return keyguardShowing && !keyguardOccluded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index adc33a1..03f42a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -246,18 +246,27 @@
return false;
}
+ public void setTouchActive(boolean touchActive) {
+ mTouchActive = touchActive;
+ mStackScrollLayout.setTouchActive(touchActive);
+ }
+
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+ boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+ if (!isCancel && mService.shouldIgnoreTouch()) {
+ return false;
+ }
if (isDown && mNotificationPanel.isFullyCollapsed()) {
mNotificationPanel.startExpandLatencyTracking();
}
if (isDown) {
- mTouchActive = true;
+ setTouchActive(true);
mTouchCancelled = false;
} else if (ev.getActionMasked() == MotionEvent.ACTION_UP
|| ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
- mTouchActive = false;
+ setTouchActive(false);
}
if (mTouchCancelled) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 7b6725b..9b0179d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -17,10 +17,18 @@
package com.android.systemui.statusbar.phone;
import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
/**
* Base class for dialogs that should appear over panels and keyguard.
@@ -59,7 +67,7 @@
setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
}
- public static void setShowForAllUsers(AlertDialog dialog, boolean show) {
+ public static void setShowForAllUsers(Dialog dialog, boolean show) {
if (show) {
dialog.getWindow().getAttributes().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -69,10 +77,40 @@
}
}
+ public static void setWindowOnTop(Dialog dialog) {
+ if (Dependency.get(KeyguardMonitor.class).isShowing()) {
+ dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_PANEL);
+ } else {
+ dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+ }
+ }
+
public static AlertDialog applyFlags(AlertDialog dialog) {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
return dialog;
}
+
+ public static void registerDismissListener(Dialog dialog) {
+ boolean[] registered = new boolean[1];
+ Context context = dialog.getContext();
+ final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (dialog != null) {
+ dialog.dismiss();
+ }
+ }
+ };
+ context.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
+ new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
+ registered[0] = true;
+ dialog.setOnDismissListener(d -> {
+ if (registered[0]) {
+ context.unregisterReceiver(mReceiver);
+ registered[0] = false;
+ }
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
index d1e4963..c0a6837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
@@ -97,8 +97,9 @@
@Override
public void scanForAccessPoints() {
- if (DEBUG) Log.d(TAG, "scan!");
- mWifiTracker.forceScan();
+ if (DEBUG) Log.d(TAG, "force update APs!");
+ mWifiTracker.forceUpdate();
+ fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 718c348..42ce4c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,14 +16,15 @@
package com.android.systemui.statusbar.policy;
+import android.util.ArraySet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
+import com.android.internal.util.Preconditions;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -31,7 +32,8 @@
/**
* Controls showing and hiding of the brightness mirror.
*/
-public class BrightnessMirrorController {
+public class BrightnessMirrorController
+ implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
private final NotificationStackScrollLayout mStackScroller;
public long TRANSITION_DURATION_OUT = 150;
@@ -40,6 +42,7 @@
private final StatusBarWindowView mStatusBarWindow;
private final ScrimController mScrimController;
private final View mNotificationPanel;
+ private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
private final int[] mInt2Cache = new int[2];
private View mBrightnessMirror;
@@ -130,5 +133,24 @@
mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate(
R.layout.brightness_mirror, mStatusBarWindow, false);
mStatusBarWindow.addView(mBrightnessMirror, index);
+
+ for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) {
+ mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror);
+ }
+ }
+
+ @Override
+ public void addCallback(BrightnessMirrorListener listener) {
+ Preconditions.checkNotNull(listener);
+ mBrightnessMirrorListeners.add(listener);
+ }
+
+ @Override
+ public void removeCallback(BrightnessMirrorListener listener) {
+ mBrightnessMirrorListeners.remove(listener);
+ }
+
+ public interface BrightnessMirrorListener {
+ void onBrightnessMirrorReinflated(View brightnessMirror);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d652bde..65bfabd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -113,6 +113,11 @@
setBackground(mRipple);
}
+ @Override
+ public boolean isClickable() {
+ return mCode != 0 || super.isClickable();
+ }
+
public void setCode(int code) {
mCode = code;
}
@@ -228,7 +233,7 @@
setPressed(false);
// Always send a release ourselves because it doesn't seem to be sent elsewhere
// and it feels weird to sometimes get a release haptic and other times not.
- if ((SystemClock.uptimeMillis() - mDownTime) > 100) {
+ if ((SystemClock.uptimeMillis() - mDownTime) > 150 && !mLongClicked) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
}
if (mCode != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index b1e4b03..527addf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -131,6 +131,7 @@
final int userId = userInfo.id;
final boolean isGuest = userInfo.isGuest();
final String userName = userInfo.name;
+ final boolean lightIcon = mContext.getThemeResId() != R.style.Theme_SystemUI_Light;
final Resources res = mContext.getResources();
final int avatarSize = Math.max(
@@ -154,7 +155,7 @@
.setIcon(rawAvatar).setBadgeIfManagedUser(mContext, userId).bake();
} else {
avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId,
- /* light= */ true);
+ lightIcon);
}
// If it's a single-user device, get the profile name, since the nickname is not
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 4bbe895..188f216 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3714,6 +3714,9 @@
* See {@link AmbientState#setDark}.
*/
public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
+ if (mAmbientState.isDark() == dark) {
+ return;
+ }
mAmbientState.setDark(dark);
if (animate && mAnimationsEnabled) {
mDarkNeedsAnimation = true;
@@ -4311,6 +4314,10 @@
mAmbientState.getScrollY()));
}
+ public void setTouchActive(boolean touchActive) {
+ mShelf.setTouchActive(touchActive);
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index f4197a3..c060b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -249,14 +249,28 @@
state.paddingMap.clear();
int notGoneIndex = 0;
ExpandableView lastView = null;
+ int firstHiddenIndex = ambientState.isDark()
+ ? (ambientState.hasPulsingNotifications() ? 1 : 0)
+ : childCount;
+
+ // The goal here is to fill the padding map, by iterating over how much padding each child
+ // needs. The map is thereby reused, by first filling it with the padding amount and when
+ // iterating over it again, it's filled with the actual resolved value.
+
for (int i = 0; i < childCount; i++) {
ExpandableView v = (ExpandableView) hostView.getChildAt(i);
if (v.getVisibility() != View.GONE) {
if (v == ambientState.getShelf()) {
continue;
}
+ if (i >= firstHiddenIndex) {
+ // we need normal padding now, to be in sync with what the stack calculates
+ lastView = null;
+ ExpandableViewState viewState = resultState.getViewStateForView(v);
+ viewState.hidden = true;
+ }
notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
- float increasedPadding = v.getIncreasedPaddingAmount();;
+ float increasedPadding = v.getIncreasedPaddingAmount();
if (increasedPadding != 0.0f) {
state.paddingMap.put(v, increasedPadding);
if (lastView != null) {
@@ -279,6 +293,8 @@
state.paddingMap.put(lastView, newValue);
}
} else if (lastView != null) {
+
+ // Let's now resolve the value to an actual padding
float newValue = getPaddingForValue(state.paddingMap.get(lastView));
state.paddingMap.put(lastView, newValue);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
new file mode 100644
index 0000000..5790ba3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -0,0 +1,162 @@
+/*
+ * 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.util;
+
+import android.hardware.HardwareBuffer;
+import android.hardware.Sensor;
+import android.hardware.SensorAdditionalInfo;
+import android.hardware.SensorDirectChannel;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEventListener;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.MemoryFile;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Wrapper around sensor manager that hides potential sources of latency.
+ *
+ * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread
+ * without blocking. Note that this means registering listeners now always appears successful even
+ * if it is not.
+ */
+public class AsyncSensorManager extends SensorManager {
+
+ private static final String TAG = "AsyncSensorManager";
+
+ private final SensorManager mInner;
+ private final List<Sensor> mSensorCache;
+ private final HandlerThread mHandlerThread = new HandlerThread("async_sensor");
+ @VisibleForTesting final Handler mHandler;
+
+ public AsyncSensorManager(SensorManager inner) {
+ mInner = inner;
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL);
+ }
+
+ @Override
+ protected List<Sensor> getFullSensorList() {
+ return mSensorCache;
+ }
+
+ @Override
+ protected List<Sensor> getFullDynamicSensorList() {
+ return mInner.getDynamicSensorList(Sensor.TYPE_ALL);
+ }
+
+ @Override
+ protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs,
+ Handler handler, int maxReportLatencyUs, int reservedFlags) {
+ mHandler.post(() -> {
+ if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) {
+ Log.e(TAG, "Registering " + listener + " for " + sensor + " failed.");
+ }
+ });
+ return true;
+ }
+
+ @Override
+ protected boolean flushImpl(SensorEventListener listener) {
+ return mInner.flush(listener);
+ }
+
+ @Override
+ protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile,
+ HardwareBuffer hardwareBuffer) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected void destroyDirectChannelImpl(SensorDirectChannel channel) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback,
+ Handler handler) {
+ mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler));
+ }
+
+ @Override
+ protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) {
+ mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback));
+ }
+
+ @Override
+ protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
+ mHandler.post(() -> {
+ if (!mInner.requestTriggerSensor(listener, sensor)) {
+ Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed.");
+ }
+ });
+ return true;
+ }
+
+ @Override
+ protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
+ boolean disable) {
+ Preconditions.checkArgument(disable);
+
+ mHandler.post(() -> {
+ if (!mInner.cancelTriggerSensor(listener, sensor)) {
+ Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed.");
+ }
+ });
+ return true;
+ }
+
+ @Override
+ protected boolean initDataInjectionImpl(boolean enable) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
+ long timestamp) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) {
+ mHandler.post(() -> mInner.setOperationParameter(parameter));
+ return true;
+ }
+
+ @Override
+ protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
+ mHandler.post(() -> {
+ if (sensor == null) {
+ mInner.unregisterListener(listener);
+ } else {
+ mInner.unregisterListener(listener, sensor);
+ }
+ });
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 8ed4fca..49a12f4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -79,14 +79,16 @@
public static final int DISMISS_REASON_SCREEN_OFF = 4;
public static final int DISMISS_REASON_SETTINGS_CLICKED = 5;
public static final int DISMISS_REASON_DONE_CLICKED = 6;
+ public static final int DISMISS_STREAM_GONE = 7;
public static final String[] DISMISS_REASONS = {
- "unknown",
- "touch_outside",
- "volume_controller",
- "timeout",
- "screen_off",
- "settings_clicked",
- "done_clicked",
+ "unknown",
+ "touch_outside",
+ "volume_controller",
+ "timeout",
+ "screen_off",
+ "settings_clicked",
+ "done_clicked",
+ "a11y_stream_changed"
};
public static final int SHOW_REASON_UNKNOWN = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 73ec0a4..b08b26d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -100,7 +100,7 @@
private final MediaSessions mMediaSessions;
protected C mCallbacks = new C();
private final State mState = new State();
- private final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
+ protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
private final Vibrator mVibrator;
private final boolean mHasVibrator;
private boolean mShowA11yStream;
@@ -906,18 +906,14 @@
}
}
- private final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
+ protected final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
private int mNextStream = DYNAMIC_STREAM_START_INDEX;
@Override
public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
- if (!mRemoteStreams.containsKey(token)) {
- mRemoteStreams.put(token, mNextStream);
- if (D.BUG) Log.d(TAG, "onRemoteUpdate: " + name + " is stream " + mNextStream);
- mNextStream++;
- }
+ addStream(token, "onRemoteUpdate");
final int stream = mRemoteStreams.get(token);
boolean changed = mState.states.indexOfKey(stream) < 0;
final StreamState ss = streamStateW(stream);
@@ -942,6 +938,7 @@
@Override
public void onRemoteVolumeChanged(Token token, int flags) {
+ addStream(token, "onRemoteVolumeChanged");
final int stream = mRemoteStreams.get(token);
final boolean showUI = shouldShowUI(flags);
boolean changed = updateActiveStreamW(stream);
@@ -958,6 +955,11 @@
@Override
public void onRemoteRemoved(Token token) {
+ if (!mRemoteStreams.containsKey(token)) {
+ if (D.BUG) Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
+ + "aborting remote removed for token:" + token.toString());
+ return;
+ }
final int stream = mRemoteStreams.get(token);
mState.states.remove(stream);
if (mState.activeStream == stream) {
@@ -983,6 +985,15 @@
}
return null;
}
+
+ private void addStream(Token token, String triggeringMethod) {
+ if (!mRemoteStreams.containsKey(token)) {
+ mRemoteStreams.put(token, mNextStream);
+ if (D.BUG) Log.d(TAG, triggeringMethod + ": added stream " + mNextStream
+ + " from token + "+ token.toString());
+ mNextStream++;
+ }
+ }
}
public interface UserActivityListener {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index fe3d4b7..7f5c595 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -760,6 +760,7 @@
// update header text
Util.setText(row.header, getStreamLabelH(ss));
+ row.slider.setContentDescription(row.header.getText());
mConfigurableTexts.add(row.header, ss.name);
// update icon
@@ -1058,7 +1059,12 @@
public void onAccessibilityModeChanged(Boolean showA11yStream) {
boolean show = showA11yStream == null ? false : showA11yStream;
mShowA11yStream = show;
- updateRowsH(getActiveRow());
+ VolumeRow activeRow = getActiveRow();
+ if (!mShowA11yStream && AudioManager.STREAM_ACCESSIBILITY == activeRow.stream) {
+ dismissH(Events.DISMISS_STREAM_GONE);
+ } else {
+ updateRowsH(activeRow);
+ }
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 4716552..a3aca6e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -41,6 +41,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
+import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -53,6 +54,7 @@
import android.widget.RadioGroup;
import android.widget.TextView;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
@@ -116,8 +118,6 @@
private Callback mCallback;
private ZenModeController mController;
- private boolean mCountdownConditionSupported;
- private boolean mRequestingConditions;
private Condition mExitCondition;
private int mBucketIndex = -1;
private boolean mExpanded;
@@ -126,8 +126,6 @@
private int mAttachedZen;
private boolean mAttached;
private Condition mSessionExitCondition;
- private Condition[] mConditions;
- private Condition mTimeCondition;
private boolean mVoiceCapable;
protected int mZenModeConditionLayoutId;
@@ -155,8 +153,6 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("ZenModePanel state:");
- pw.print(" mCountdownConditionSupported="); pw.println(mCountdownConditionSupported);
- pw.print(" mRequestingConditions="); pw.println(mRequestingConditions);
pw.print(" mAttached="); pw.println(mAttached);
pw.print(" mHidden="); pw.println(mHidden);
pw.print(" mExpanded="); pw.println(mExpanded);
@@ -292,7 +288,6 @@
private void onAttach() {
setExpanded(true);
- mAttached = true;
mAttachedZen = mController.getZen();
ZenRule manualRule = mController.getManualRule();
mExitCondition = manualRule != null ? manualRule.condition : null;
@@ -304,23 +299,26 @@
mController.addCallback(mZenCallback);
setSessionExitCondition(copy(mExitCondition));
updateWidgets();
- setRequestingConditions(!mHidden);
- ensureSelection();
+ setAttached(true);
}
private void onDetach() {
if (DEBUG) Log.d(mTag, "onDetach");
setExpanded(false);
checkForAttachedZenChange();
- mAttached = false;
+ setAttached(false);
mAttachedZen = -1;
mSessionZen = -1;
mController.removeCallback(mZenCallback);
setSessionExitCondition(null);
- setRequestingConditions(false);
mTransitionHelper.clear();
}
+ @VisibleForTesting
+ void setAttached(boolean attached) {
+ mAttached = attached;
+ }
+
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
@@ -342,7 +340,6 @@
if (mHidden == hidden) return;
if (DEBUG) Log.d(mTag, "hidden=" + hidden);
mHidden = hidden;
- setRequestingConditions(mAttached && !mHidden);
updateWidgets();
}
@@ -365,29 +362,6 @@
fireExpanded();
}
- /** Start or stop requesting relevant zen mode exit conditions */
- private void setRequestingConditions(final boolean requesting) {
- if (mRequestingConditions == requesting) return;
- if (DEBUG) Log.d(mTag, "setRequestingConditions " + requesting);
- mRequestingConditions = requesting;
- if (mRequestingConditions) {
- mTimeCondition = parseExistingTimeCondition(mContext, mExitCondition);
- if (mTimeCondition != null) {
- mBucketIndex = -1;
- } else {
- mBucketIndex = DEFAULT_BUCKET_INDEX;
- mTimeCondition = ZenModeConfig.toTimeCondition(mContext,
- MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
- }
- if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex);
-
- mConditions = null; // reset conditions
- handleUpdateConditions();
- } else {
- hideAllConditions();
- }
- }
-
protected void addZenConditions(int count) {
for (int i = 0; i < count; i++) {
final View rb = mInflater.inflate(mZenModeButtonLayoutId, mEdit, false);
@@ -401,9 +375,7 @@
public void init(ZenModeController controller) {
mController = controller;
- mCountdownConditionSupported = mController.isCountdownConditionSupported();
- final int countdownDelta = mCountdownConditionSupported ? COUNTDOWN_CONDITION_COUNT : 0;
- final int minConditions = 1 /*forever*/ + countdownDelta;
+ final int minConditions = 1 /*forever*/ + COUNTDOWN_CONDITION_COUNT;
addZenConditions(minConditions);
mSessionZen = getSelectedZen(-1);
handleUpdateManualRule(mController.getManualRule());
@@ -426,10 +398,6 @@
return isForever(condition) ? null : getConditionId(condition);
}
- private static boolean sameConditionId(Condition lhs, Condition rhs) {
- return lhs == null ? rhs == null : rhs != null && lhs.id.equals(rhs.id);
- }
-
private static Condition copy(Condition condition) {
return condition == null ? null : condition.copy();
}
@@ -438,17 +406,24 @@
mCallback = callback;
}
- private void handleUpdateManualRule(ZenRule rule) {
+ @VisibleForTesting
+ void handleUpdateManualRule(ZenRule rule) {
final int zen = rule != null ? rule.zenMode : Global.ZEN_MODE_OFF;
handleUpdateZen(zen);
final Condition c = rule == null ? null
: rule.condition != null ? rule.condition
: createCondition(rule.conditionId);
- handleExitConditionChanged(c);
+ handleUpdateConditions(c);
+ setExitCondition(c);
}
private Condition createCondition(Uri conditionId) {
- if (ZenModeConfig.isValidCountdownConditionId(conditionId)) {
+ if (ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId)) {
+ long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+ Condition c = ZenModeConfig.toNextAlarmCondition(
+ mContext, time, ActivityManager.getCurrentUser());
+ return c;
+ } else if (ZenModeConfig.isValidCountdownConditionId(conditionId)) {
long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
int mins = (int) ((time - System.currentTimeMillis() + DateUtils.MINUTE_IN_MILLIS / 2)
/ DateUtils.MINUTE_IN_MILLIS);
@@ -466,48 +441,10 @@
}
mZenButtons.setSelectedValue(zen, false /* fromClick */);
updateWidgets();
- handleUpdateConditions();
- if (mExpanded) {
- final Condition selected = getSelectedCondition();
- if (!Objects.equals(mExitCondition, selected)) {
- select(selected);
- }
- }
}
- private void handleExitConditionChanged(Condition exitCondition) {
- setExitCondition(exitCondition);
- if (DEBUG) Log.d(mTag, "handleExitConditionChanged " + mExitCondition);
- if (exitCondition == null) return;
- final int N = getVisibleConditions();
- for (int i = 0; i < N; i++) {
- final ConditionTag tag = getConditionTagAt(i);
- if (tag != null && sameConditionId(tag.condition, mExitCondition)) {
- bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
- tag.rb.setChecked(true);
- return;
- }
- }
- if (mCountdownConditionSupported && ZenModeConfig.isValidCountdownConditionId(
- exitCondition.id)) {
- bind(exitCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
- COUNTDOWN_CONDITION_INDEX);
- getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
- }
- }
-
- private Condition getSelectedCondition() {
- final int N = getVisibleConditions();
- for (int i = 0; i < N; i++) {
- final ConditionTag tag = getConditionTagAt(i);
- if (tag != null && tag.rb.isChecked()) {
- return tag.condition;
- }
- }
- return null;
- }
-
- private int getSelectedZen(int defValue) {
+ @VisibleForTesting
+ int getSelectedZen(int defValue) {
final Object zen = mZenButtons.getSelectedValue();
return zen != null ? (Integer) zen : defValue;
}
@@ -575,56 +512,66 @@
return getResources().getString(warningRes, template);
}
- private static Condition parseExistingTimeCondition(Context context, Condition condition) {
- if (condition == null) return null;
- final long time = ZenModeConfig.tryParseCountdownConditionId(condition.id);
- if (time == 0) return null;
- final long now = System.currentTimeMillis();
- final long span = time - now;
- if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null;
- return ZenModeConfig.toTimeCondition(context,
- time, Math.round(span / (float) MINUTES_MS), ActivityManager.getCurrentUser(),
- false /*shortVersion*/);
- }
-
- private void handleUpdateConditions() {
+ @VisibleForTesting
+ void handleUpdateConditions(Condition c) {
if (mTransitionHelper.isTransitioning()) {
return;
}
- final int conditionCount = mConditions == null ? 0 : mConditions.length;
- if (DEBUG) Log.d(mTag, "handleUpdateConditions conditionCount=" + conditionCount);
// forever
bind(forever(), mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
FOREVER_CONDITION_INDEX);
- // countdown
- if (mCountdownConditionSupported && mTimeCondition != null) {
- bind(mTimeCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
- COUNTDOWN_CONDITION_INDEX);
- }
- // countdown until alarm
- if (mCountdownConditionSupported) {
- Condition nextAlarmCondition = getTimeUntilNextAlarmCondition();
- if (nextAlarmCondition != null) {
- mZenRadioGroup.getChildAt(
- COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
- mZenRadioGroupContent.getChildAt(
- COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
- bind(nextAlarmCondition,
- mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX),
- COUNTDOWN_ALARM_CONDITION_INDEX);
+ if (c == null) {
+ bindGenericCountdown();
+ bindNextAlarm(getTimeUntilNextAlarmCondition());
+ } else if (isForever(c)) {
+ getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
+ bindGenericCountdown();
+ bindNextAlarm(getTimeUntilNextAlarmCondition());
+ } else {
+ if (isAlarm(c)) {
+ bindGenericCountdown();
+
+ bindNextAlarm(c);
+ getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.setChecked(true);
+ } else if (isCountdown(c)) {
+ bindNextAlarm(getTimeUntilNextAlarmCondition());
+
+ bind(c, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ COUNTDOWN_CONDITION_INDEX);
+ getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
} else {
- mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
- mZenRadioGroupContent.getChildAt(
- COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
+ Slog.wtf(TAG, "Invalid manual condition: " + c);
}
}
- // ensure something is selected
- if (mExpanded) {
- ensureSelection();
- }
mZenConditions.setVisibility(mSessionZen != Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
}
+ private void bindGenericCountdown() {
+ mBucketIndex = DEFAULT_BUCKET_INDEX;
+ Condition countdown = ZenModeConfig.toTimeCondition(mContext,
+ MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
+ // don't change the hour condition while the user is viewing the panel
+ if (!mAttached || getConditionTagAt(COUNTDOWN_CONDITION_INDEX).condition == null) {
+ bind(countdown, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ COUNTDOWN_CONDITION_INDEX);
+ }
+ }
+
+ private void bindNextAlarm(Condition c) {
+ View alarmContent = mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX);
+ ConditionTag tag = (ConditionTag) alarmContent.getTag();
+ // Don't change the alarm condition while the user is viewing the panel
+ if (c != null && (!mAttached || tag == null || tag.condition == null)) {
+ bind(c, alarmContent, COUNTDOWN_ALARM_CONDITION_INDEX);
+ }
+
+ tag = (ConditionTag) alarmContent.getTag();
+ boolean showAlarm = tag != null && tag.condition != null;
+ mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(
+ showAlarm ? View.VISIBLE : View.GONE);
+ alarmContent.setVisibility(showAlarm ? View.VISIBLE : View.GONE);
+ }
+
private Condition forever() {
return new Condition(mForeverId, foreverSummary(mContext), "", "", 0 /*icon*/,
Condition.STATE_TRUE, 0 /*flags*/);
@@ -637,7 +584,6 @@
// Returns a time condition if the next alarm is within the next week.
private Condition getTimeUntilNextAlarmCondition() {
GregorianCalendar weekRange = new GregorianCalendar();
- final long now = weekRange.getTimeInMillis();
setToMidnight(weekRange);
weekRange.add(Calendar.DATE, 6);
final long nextAlarmMs = mController.getNextAlarm();
@@ -647,9 +593,8 @@
setToMidnight(nextAlarm);
if (weekRange.compareTo(nextAlarm) >= 0) {
- return ZenModeConfig.toTimeCondition(mContext, nextAlarmMs,
- Math.round((nextAlarmMs - now) / (float) MINUTES_MS),
- ActivityManager.getCurrentUser(), true);
+ return ZenModeConfig.toNextAlarmCondition(mContext, nextAlarmMs,
+ ActivityManager.getCurrentUser());
}
}
return null;
@@ -662,11 +607,13 @@
calendar.set(Calendar.MILLISECOND, 0);
}
- private ConditionTag getConditionTagAt(int index) {
+ @VisibleForTesting
+ ConditionTag getConditionTagAt(int index) {
return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
}
- private int getVisibleConditions() {
+ @VisibleForTesting
+ int getVisibleConditions() {
int rt = 0;
final int N = mZenRadioGroupContent.getChildCount();
for (int i = 0; i < N; i++) {
@@ -682,34 +629,8 @@
}
}
- private void ensureSelection() {
- // are we left without anything selected? if so, set a default
- final int visibleConditions = getVisibleConditions();
- if (visibleConditions == 0) return;
- for (int i = 0; i < visibleConditions; i++) {
- final ConditionTag tag = getConditionTagAt(i);
- if (tag != null && tag.rb.isChecked()) {
- if (DEBUG) Log.d(mTag, "Not selecting a default, checked=" + tag.condition);
- return;
- }
- }
- final ConditionTag foreverTag = getConditionTagAt(FOREVER_CONDITION_INDEX);
- if (foreverTag == null) return;
- if (DEBUG) Log.d(mTag, "Selecting a default");
- final int favoriteIndex = mPrefs.getMinuteIndex();
- if (mExitCondition != null && mExitCondition.equals(mTimeCondition)) {
- getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
- } else if (favoriteIndex == -1 || !mCountdownConditionSupported ||
- mAttachedZen != Global.ZEN_MODE_OFF) {
- foreverTag.rb.setChecked(true);
- } else {
- mTimeCondition = ZenModeConfig.toTimeCondition(mContext,
- MINUTE_BUCKETS[favoriteIndex], ActivityManager.getCurrentUser());
- mBucketIndex = favoriteIndex;
- bind(mTimeCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
- COUNTDOWN_CONDITION_INDEX);
- getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
- }
+ private static boolean isAlarm(Condition c) {
+ return c != null && ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);
}
private static boolean isCountdown(Condition c) {
@@ -877,10 +798,9 @@
newCondition = ZenModeConfig.toTimeCondition(mContext,
MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
}
- mTimeCondition = newCondition;
- bind(mTimeCondition, row, rowId);
+ bind(newCondition, row, rowId);
tag.rb.setChecked(true);
- select(mTimeCondition);
+ select(newCondition);
announceConditionSelection(tag);
}
@@ -902,7 +822,7 @@
setExitCondition(condition);
if (realConditionId == null) {
mPrefs.setMinuteIndex(-1);
- } else if (isCountdown(condition) && mBucketIndex != -1) {
+ } else if ((isAlarm(condition) || isCountdown(condition)) && mBucketIndex != -1) {
mPrefs.setMinuteIndex(mBucketIndex);
}
setSessionExitCondition(copy(condition));
@@ -951,7 +871,8 @@
}
// used as the view tag on condition rows
- private static class ConditionTag {
+ @VisibleForTesting
+ static class ConditionTag {
RadioButton rb;
View lines;
TextView line1;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
new file mode 100644
index 0000000..5dbcd8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.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.systemui.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Specialized layout for zen mode that allows the radio buttons to reside within
+ * a RadioGroup, but also makes sure that all the heights off the radio buttons align
+ * with the corresponding content in the second child of this view.
+ */
+public class ZenRadioLayout extends LinearLayout {
+
+ public ZenRadioLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ /**
+ * Run 2 measurement passes, 1 that figures out the size of the content, and another
+ * that sets the size of the radio buttons to the heights of the corresponding content.
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ ViewGroup radioGroup = (ViewGroup) getChildAt(0);
+ ViewGroup radioContent = (ViewGroup) getChildAt(1);
+ int size = radioGroup.getChildCount();
+ if (size != radioContent.getChildCount()) {
+ throw new IllegalStateException("Expected matching children");
+ }
+ boolean hasChanges = false;
+ for (int i = 0; i < size; i++) {
+ View radio = radioGroup.getChildAt(i);
+ View content = radioContent.getChildAt(i);
+ if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
+ hasChanges = true;
+ radio.getLayoutParams().height = content.getMeasuredHeight();
+ }
+ }
+ // Measure again if any heights changed.
+ if (hasChanges) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index 641f263..333e73d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -87,6 +87,10 @@
}
@Override
+ public void onIgnoreTouchWhilePulsing(boolean ignore) {
+ }
+
+ @Override
public void abortPulsing() {
pulseAborted = true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index fe3221a..c275806 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -51,14 +51,16 @@
DozeScreenBrightness mScreen;
FakeSensorManager.FakeGenericSensor mSensor;
FakeSensorManager mSensorManager;
+ DozeHostFake mHostFake;
@Before
public void setUp() throws Exception {
mServiceFake = new DozeServiceFake();
+ mHostFake = new DozeHostFake();
mSensorManager = new FakeSensorManager(mContext);
mSensor = mSensorManager.getFakeLightSensor();
mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
- mSensor.getSensor(), null /* handler */);
+ mSensor.getSensor(), mHostFake, null /* handler */);
}
@Test
@@ -133,7 +135,7 @@
@Test
public void testNullSensor() throws Exception {
mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
- null /* sensor */, null /* handler */);
+ null /* sensor */, mHostFake, null /* handler */);
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
new file mode 100644
index 0000000..ed1491d3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class NearestTouchFrameTest extends SysuiTestCase {
+
+ private NearestTouchFrame mNearestTouchFrame;
+
+ @Before
+ public void setup() {
+ Configuration c = new Configuration(mContext.getResources().getConfiguration());
+ c.smallestScreenWidthDp = 500;
+ mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+ }
+
+ @Test
+ public void testNoActionOnLargeDevices() {
+ Configuration c = new Configuration(mContext.getResources().getConfiguration());
+ c.smallestScreenWidthDp = 700;
+ mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+
+ View left = mockViewAt(0, 0, 10, 10);
+ View right = mockViewAt(20, 0, 10, 10);
+
+ mNearestTouchFrame.addView(left);
+ mNearestTouchFrame.addView(right);
+ mNearestTouchFrame.onMeasure(0, 0);
+
+ MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+ 12 /* x */, 5 /* y */, 0);
+ mNearestTouchFrame.onTouchEvent(ev);
+ verify(left, never()).onTouchEvent(eq(ev));
+ ev.recycle();
+ }
+
+ @Test
+ public void testHorizontalSelection_Left() {
+ View left = mockViewAt(0, 0, 10, 10);
+ View right = mockViewAt(20, 0, 10, 10);
+
+ mNearestTouchFrame.addView(left);
+ mNearestTouchFrame.addView(right);
+ mNearestTouchFrame.onMeasure(0, 0);
+
+ MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+ 12 /* x */, 5 /* y */, 0);
+ mNearestTouchFrame.onTouchEvent(ev);
+ verify(left).onTouchEvent(eq(ev));
+ ev.recycle();
+ }
+
+ @Test
+ public void testHorizontalSelection_Right() {
+ View left = mockViewAt(0, 0, 10, 10);
+ View right = mockViewAt(20, 0, 10, 10);
+
+ mNearestTouchFrame.addView(left);
+ mNearestTouchFrame.addView(right);
+ mNearestTouchFrame.onMeasure(0, 0);
+
+ MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+ 18 /* x */, 5 /* y */, 0);
+ mNearestTouchFrame.onTouchEvent(ev);
+ verify(right).onTouchEvent(eq(ev));
+ ev.recycle();
+ }
+
+ @Test
+ public void testVerticalSelection_Top() {
+ View top = mockViewAt(0, 0, 10, 10);
+ View bottom = mockViewAt(0, 20, 10, 10);
+
+ mNearestTouchFrame.addView(top);
+ mNearestTouchFrame.addView(bottom);
+ mNearestTouchFrame.onMeasure(0, 0);
+
+ MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+ 5 /* x */, 12 /* y */, 0);
+ mNearestTouchFrame.onTouchEvent(ev);
+ verify(top).onTouchEvent(eq(ev));
+ ev.recycle();
+ }
+
+ @Test
+ public void testVerticalSelection_Bottom() {
+ View top = mockViewAt(0, 0, 10, 10);
+ View bottom = mockViewAt(0, 20, 10, 10);
+
+ mNearestTouchFrame.addView(top);
+ mNearestTouchFrame.addView(bottom);
+ mNearestTouchFrame.onMeasure(0, 0);
+
+ MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+ 5 /* x */, 18 /* y */, 0);
+ mNearestTouchFrame.onTouchEvent(ev);
+ verify(bottom).onTouchEvent(eq(ev));
+ ev.recycle();
+ }
+
+ private View mockViewAt(int x, int y, int width, int height) {
+ View v = spy(new View(mContext));
+ doAnswer(invocation -> {
+ int[] pos = (int[]) invocation.getArguments()[0];
+ pos[0] = x;
+ pos[1] = y;
+ return null;
+ }).when(v).getLocationInWindow(any());
+ when(v.isClickable()).thenReturn(true);
+
+ // Stupid final methods.
+ v.setLeft(0);
+ v.setRight(width);
+ v.setTop(0);
+ v.setBottom(height);
+ return v;
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index c33897e..a706368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -65,6 +65,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.CommandQueue;
@@ -500,6 +501,14 @@
mSystemServicesProxy = ssp;
mNotificationPanel = panelView;
mBarService = barService;
+ mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
+ }
+
+ private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
+ WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+ wakefulnessLifecycle.dispatchStartedWakingUp();
+ wakefulnessLifecycle.dispatchFinishedWakingUp();
+ return wakefulnessLifecycle;
}
public void setBarStateForTest(int state) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
new file mode 100644
index 0000000..469bdc0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.utils.hardware.FakeSensorManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class AsyncSensorManagerTest extends SysuiTestCase {
+
+ private TestableAsyncSensorManager mAsyncSensorManager;
+ private FakeSensorManager mFakeSensorManager;
+ private SensorEventListener mListener;
+ private FakeSensorManager.MockProximitySensor mSensor;
+
+ @Before
+ public void setUp() throws Exception {
+ mFakeSensorManager = new FakeSensorManager(mContext);
+ mAsyncSensorManager = new TestableAsyncSensorManager(mFakeSensorManager);
+ mSensor = mFakeSensorManager.getMockProximitySensor();
+ mListener = mock(SensorEventListener.class);
+ }
+
+ @Test
+ public void registerListenerImpl() throws Exception {
+ mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+
+ mAsyncSensorManager.waitUntilRequestsCompleted();
+
+ // Verify listener was registered.
+ mSensor.sendProximityResult(true);
+ verify(mListener).onSensorChanged(any());
+ }
+
+ @Test
+ public void unregisterListenerImpl_withNullSensor() throws Exception {
+ mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+ mAsyncSensorManager.unregisterListener(mListener);
+
+ mAsyncSensorManager.waitUntilRequestsCompleted();
+
+ // Verify listener was unregistered.
+ mSensor.sendProximityResult(true);
+ verifyNoMoreInteractions(mListener);
+ }
+
+ @Test
+ public void unregisterListenerImpl_withSensor() throws Exception {
+ mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+ mAsyncSensorManager.unregisterListener(mListener, mSensor.getSensor());
+
+ mAsyncSensorManager.waitUntilRequestsCompleted();
+
+ // Verify listener was unregistered.
+ mSensor.sendProximityResult(true);
+ verifyNoMoreInteractions(mListener);
+ }
+
+ private class TestableAsyncSensorManager extends AsyncSensorManager {
+ public TestableAsyncSensorManager(SensorManager sensorManager) {
+ super(sensorManager);
+ }
+
+ public void waitUntilRequestsCompleted() {
+ assertTrue(mHandler.runWithScissors(() -> {}, 0));
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
index 12e9f7c..06568f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.media.AudioManager;
+import android.media.session.MediaSession;
import android.support.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -73,6 +74,18 @@
verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
}
+ @Test
+ public void testOnRemoteVolumeChanged_newStream_noNullPointer() {
+ MediaSession.Token token = new MediaSession.Token(null);
+ mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0);
+ }
+
+ @Test
+ public void testOnRemoteRemove_newStream_noNullPointer() {
+ MediaSession.Token token = new MediaSession.Token(null);
+ mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(token);
+ }
+
static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl {
public TestableVolumeDialogControllerImpl(Context context, C callback, StatusBar s) {
super(context);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java
new file mode 100644
index 0000000..0fdbfd1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java
@@ -0,0 +1,217 @@
+/**
+ * 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.volume;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.net.Uri;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.LayoutInflater;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ZenModePanelTest extends SysuiTestCase {
+
+ ZenModePanel mPanel;
+ ZenModeController mController;
+ Uri mForeverId;
+
+ @Before
+ public void setup() throws Exception {
+ final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+ mPanel = (ZenModePanel) layoutInflater.inflate(com.android.systemui.R.layout.zen_mode_panel,
+ null);
+ mController = mock(ZenModeController.class);
+ mForeverId = Condition.newId(mContext).appendPath("forever").build();
+
+ mPanel.init(mController);
+ }
+
+ private void assertProperConditionTagTypes(boolean hasAlarm) {
+ final int N = mPanel.getVisibleConditions();
+ assertEquals(hasAlarm ? 3 : 2, N);
+
+ assertEquals(mForeverId, mPanel.getConditionTagAt(0).condition.id);
+ assertTrue(ZenModeConfig.isValidCountdownConditionId(
+ mPanel.getConditionTagAt(1).condition.id));
+ assertFalse(ZenModeConfig.isValidCountdownToAlarmConditionId(
+ mPanel.getConditionTagAt(1).condition.id));
+ if (hasAlarm) {
+ assertTrue(ZenModeConfig.isValidCountdownToAlarmConditionId(
+ mPanel.getConditionTagAt(2).condition.id));
+ }
+ }
+
+ @Test
+ public void testHandleUpdateConditions_foreverSelected_alarmExists() {
+ Condition forever = new Condition(mForeverId, "", Condition.STATE_TRUE);
+
+ when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
+
+ mPanel.handleUpdateConditions(forever);
+ assertProperConditionTagTypes(true);
+ assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
+ }
+
+ @Test
+ public void testHandleUpdateConditions_foreverSelected_noAlarm() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+ Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
+
+ when(mController.getNextAlarm()).thenReturn((long) 0);
+
+ mPanel.handleUpdateConditions(forever);
+ assertProperConditionTagTypes(false);
+ assertEquals(foreverId, mPanel.getConditionTagAt(0).condition.id);
+ }
+
+ @Test
+ public void testHandleUpdateConditions_countdownSelected_alarmExists() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+
+ Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
+ "", Condition.STATE_TRUE);
+
+ when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
+
+ mPanel.handleUpdateConditions(countdown);
+ assertProperConditionTagTypes(true);
+ assertTrue(mPanel.getConditionTagAt(1).rb.isChecked());
+ }
+
+ @Test
+ public void testHandleUpdateConditions_countdownSelected_noAlarm() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+
+ Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
+ "", Condition.STATE_TRUE);
+
+ when(mController.getNextAlarm()).thenReturn((long) 0);
+
+ mPanel.handleUpdateConditions(countdown);
+ assertProperConditionTagTypes(false);
+ assertTrue(mPanel.getConditionTagAt(1).rb.isChecked());
+ }
+
+ @Test
+ public void testHandleUpdateConditions_nextAlarmSelected() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+
+ Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + 1000, true),
+ "", Condition.STATE_TRUE);
+ when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 9000);
+
+ mPanel.handleUpdateConditions(alarm);
+
+ assertProperConditionTagTypes(true);
+ assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
+ assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
+ }
+
+ @Test
+ public void testHandleUpdateConditions_foreverSelected_alarmConditionDoesNotChangeIfAttached() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+ Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
+
+ Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + 9000, true),
+ "", Condition.STATE_TRUE);
+ when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
+
+ mPanel.handleUpdateConditions(alarm);
+ mPanel.setAttached(true);
+ mPanel.handleUpdateConditions(forever);
+
+ assertProperConditionTagTypes(true);
+ assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
+ assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
+ }
+
+ @Test
+ public void testHandleUpdateConditions_foreverSelected_timeConditionDoesNotChangeIfAttached() {
+ Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+ Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
+
+ Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
+ "", Condition.STATE_TRUE);
+ when(mController.getNextAlarm()).thenReturn((long) 0);
+
+ mPanel.handleUpdateConditions(countdown);
+ mPanel.setAttached(true);
+ mPanel.handleUpdateConditions(forever);
+
+ assertProperConditionTagTypes(false);
+ assertEquals(countdown, mPanel.getConditionTagAt(1).condition);
+ assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testHandleUpdateManualRule_stillSelectedAfterModeChange() {
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+
+ Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
+ System.currentTimeMillis() + 1000, true),
+ "", Condition.STATE_TRUE);
+
+ rule.condition = alarm;
+ rule.conditionId = alarm.id;
+ rule.enabled = true;
+ rule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+
+ mPanel.handleUpdateManualRule(rule);
+
+ assertProperConditionTagTypes(true);
+ assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
+ assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
+
+ assertEquals(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ mPanel.getSelectedZen(Settings.Global.ZEN_MODE_OFF));
+
+ rule.zenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+ mPanel.handleUpdateManualRule(rule);
+
+ assertProperConditionTagTypes(true);
+ assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
+ assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
+
+ assertEquals(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS,
+ mPanel.getSelectedZen(Settings.Global.ZEN_MODE_OFF));
+ }
+}
diff --git a/packages/VpnDialogs/res/values-en-rXC/strings.xml b/packages/VpnDialogs/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..640a41d
--- /dev/null
+++ b/packages/VpnDialogs/res/values-en-rXC/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="prompt" msgid="3183836924226407828">"Connection request"</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wants to set up a VPN connection that allows it to monitor network traffic. Only accept if you trust the source. <br /> <br /> <img src=vpn_icon /> appears at the top of your screen when VPN is active."</string>
+ <string name="legacy_title" msgid="192936250066580964">"VPN is connected"</string>
+ <string name="configure" msgid="4905518375574791375">"Configure"</string>
+ <string name="disconnect" msgid="971412338304200056">"Disconnect"</string>
+ <string name="session" msgid="6470628549473641030">"Session:"</string>
+ <string name="duration" msgid="3584782459928719435">"Duration:"</string>
+ <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
+ <string name="data_received" msgid="4062776929376067820">"Received:"</string>
+ <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
+</resources>
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 28e3427..c4dc506 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -276,6 +276,42 @@
// Count of saved Passpoint providers device has ever connected to.
optional int32 num_passpoint_providers_successfully_connected = 63;
+
+ // Histogram counting instances of scans with N many ScanResults with unique ssids
+ repeated NumConnectableNetworksBucket total_ssids_in_scan_histogram = 64;
+
+ // Histogram counting instances of scans with N many ScanResults/bssids
+ repeated NumConnectableNetworksBucket total_bssids_in_scan_histogram = 65;
+
+ // Histogram counting instances of scans with N many unique open ssids
+ repeated NumConnectableNetworksBucket available_open_ssids_in_scan_histogram = 66;
+
+ // Histogram counting instances of scans with N many bssids for open networks
+ repeated NumConnectableNetworksBucket available_open_bssids_in_scan_histogram = 67;
+
+ // Histogram counting instances of scans with N many unique ssids for saved networks
+ repeated NumConnectableNetworksBucket available_saved_ssids_in_scan_histogram = 68;
+
+ // Histogram counting instances of scans with N many bssids for saved networks
+ repeated NumConnectableNetworksBucket available_saved_bssids_in_scan_histogram = 69;
+
+ // Histogram counting instances of scans with N many unique SSIDs for open or saved networks
+ repeated NumConnectableNetworksBucket available_open_or_saved_ssids_in_scan_histogram = 70;
+
+ // Histogram counting instances of scans with N many BSSIDs for open or saved networks
+ repeated NumConnectableNetworksBucket available_open_or_saved_bssids_in_scan_histogram = 71;
+
+ // Histogram counting instances of scans with N many ScanResults matching unique saved passpoint providers
+ repeated NumConnectableNetworksBucket available_saved_passpoint_provider_profiles_in_scan_histogram = 72;
+
+ // Histogram counting instances of scans with N many ScanResults BSSIDs matching a saved passpoint provider
+ repeated NumConnectableNetworksBucket available_saved_passpoint_provider_bssids_in_scan_histogram = 73;
+
+ // Counts the number of AllSingleScanLister.onResult calls with a full band scan result
+ optional int32 full_band_all_single_scan_listener_results = 74;
+
+ // Counts the number of AllSingleScanLister.onResult calls with a partial (channels) scan result
+ optional int32 partial_all_single_scan_listener_results = 75;
}
// Information that gets logged for every WiFi connection.
@@ -883,3 +919,11 @@
}
}
+// Data point used to build 'Number of Connectable Network' histograms
+message NumConnectableNetworksBucket {
+ // Number of connectable networks seen in a scan result
+ optional int32 num_connectable_networks = 1 [default = 0];
+
+ // Number of scan results with num_connectable_networks
+ optional int32 count = 2 [default = 0];
+}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 86e32e0..086dd29 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,11 +16,16 @@
package com.android.server.autofill;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
+import android.service.autofill.Dataset;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
@@ -82,4 +87,16 @@
}
return array;
}
+
+ @NonNull
+ static ArrayMap<AutofillId, AutofillValue> getFields(@NonNull Dataset dataset) {
+ final ArrayList<AutofillId> ids = dataset.getFieldIds();
+ final ArrayList<AutofillValue> values = dataset.getFieldValues();
+ final int size = ids == null ? 0 : ids.size();
+ final ArrayMap<AutofillId, AutofillValue> fields = new ArrayMap<>(size);
+ for (int i = 0; i < size; i++) {
+ fields.put(ids.get(i), values.get(i));
+ }
+ return fields;
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index a38b9d3f4..f8fb13a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -715,7 +715,13 @@
+ id + " destroyed");
return;
}
-
+ if (mResponses == null) {
+ // Typically happens when app explicitly called cancel() while the service was showing
+ // the auth UI.
+ Slog.w(TAG, "setAuthenticationResultLocked(" + authenticationId + "): no responses");
+ removeSelf();
+ return;
+ }
final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
final FillResponse authenticatedResponse = mResponses.get(requestId);
if (authenticatedResponse == null || data == null) {
@@ -781,7 +787,7 @@
return true;
}
- final int lastResponseIdx = getLastResponseIndex();
+ final int lastResponseIdx = getLastResponseIndexLocked();
if (lastResponseIdx < 0) {
Slog.w(TAG, "showSaveLocked(): did not get last response. mResponses=" + mResponses
+ ", mViewStates=" + mViewStates);
@@ -798,15 +804,20 @@
/*
* The Save dialog is only shown if all conditions below are met:
*
- * - saveInfo is not null
- * - autofillValue of all required ids is not null
+ * - saveInfo is not null.
+ * - autofillValue of all required ids is not null.
* - autofillValue of at least one id (required or optional) has changed.
+ * - there is no Dataset in the last FillResponse whose values of all dataset fields matches
+ * the current values of all fields in the screen.
*/
-
if (saveInfo == null) {
return true;
}
+ // Cache used to make sure changed fields do not belong to a dataset.
+ final ArrayMap<AutofillId, AutofillValue> currentValues = new ArrayMap<>();
+ final ArraySet<AutofillId> allIds = new ArraySet<>();
+
final AutofillId[] requiredIds = saveInfo.getRequiredIds();
boolean allRequiredAreNotEmpty = true;
boolean atLeastOneChanged = false;
@@ -817,6 +828,7 @@
Slog.w(TAG, "null autofill id on " + Arrays.toString(requiredIds));
continue;
}
+ allIds.add(id);
final ViewState viewState = mViewStates.get(id);
if (viewState == null) {
Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id);
@@ -835,18 +847,19 @@
value = initialValue;
} else {
if (sDebug) {
- Slog.d(TAG, "showSaveLocked(): empty value for required " + id );
+ Slog.d(TAG, "empty value for required " + id );
}
allRequiredAreNotEmpty = false;
break;
}
}
+ currentValues.put(id, value);
final AutofillValue filledValue = viewState.getAutofilledValue();
if (!value.equals(filledValue)) {
if (sDebug) {
- Slog.d(TAG, "showSaveLocked(): found a change on required " + id + ": "
- + filledValue + " => " + value);
+ Slog.d(TAG, "found a change on required " + id + ": " + filledValue
+ + " => " + value);
}
atLeastOneChanged = true;
}
@@ -859,22 +872,34 @@
// No change on required ids yet, look for changes on optional ids.
for (int i = 0; i < optionalIds.length; i++) {
final AutofillId id = optionalIds[i];
+ allIds.add(id);
final ViewState viewState = mViewStates.get(id);
if (viewState == null) {
- Slog.w(TAG, "showSaveLocked(): no ViewState for optional " + id);
+ Slog.w(TAG, "no ViewState for optional " + id);
continue;
}
if ((viewState.getState() & ViewState.STATE_CHANGED) != 0) {
final AutofillValue currentValue = viewState.getCurrentValue();
+ currentValues.put(id, currentValue);
final AutofillValue filledValue = viewState.getAutofilledValue();
if (currentValue != null && !currentValue.equals(filledValue)) {
if (sDebug) {
- Slog.d(TAG, "finishSessionLocked(): found a change on optional "
- + id + ": " + filledValue + " => " + currentValue);
+ Slog.d(TAG, "found a change on optional " + id + ": " + filledValue
+ + " => " + currentValue);
}
atLeastOneChanged = true;
break;
}
+ } else {
+ // Update current values cache based on initial value
+ final AutofillValue initialValue = getValueFromContexts(id);
+ if (sDebug) {
+ Slog.d(TAG, "no current value for " + id + "; initial value is "
+ + initialValue);
+ }
+ if (initialValue != null) {
+ currentValues.put(id, initialValue);
+ }
}
}
}
@@ -901,6 +926,42 @@
}
}
+ // Make sure the service doesn't have the fields already by checking the datasets
+ // content.
+ final List<Dataset> datasets = response.getDatasets();
+ if (datasets != null) {
+ datasets_loop: for (int i = 0; i < datasets.size(); i++) {
+ final Dataset dataset = datasets.get(i);
+ final ArrayMap<AutofillId, AutofillValue> datasetValues =
+ Helper.getFields(dataset);
+ if (sVerbose) {
+ Slog.v(TAG, "Checking if saved fields match contents of dataset #" + i
+ + ": " + dataset + "; allIds=" + allIds);
+ }
+ for (int j = 0; j < allIds.size(); j++) {
+ final AutofillId id = allIds.valueAt(j);
+ final AutofillValue currentValue = currentValues.get(id);
+ if (currentValue == null) {
+ if (sDebug) {
+ Slog.d(TAG, "dataset has value for field that is null: " + id);
+ }
+ continue datasets_loop;
+ }
+ final AutofillValue datasetValue = datasetValues.get(id);
+ if (!currentValue.equals(datasetValue)) {
+ if (sDebug) Slog.d(TAG, "found a change on id " + id);
+ continue datasets_loop;
+ }
+ if (sVerbose) Slog.v(TAG, "no changes for id " + id);
+ }
+ if (sDebug) {
+ Slog.d(TAG, "ignoring Save UI because all fields match contents of "
+ + "dataset #" + i + ": " + dataset);
+ }
+ return true;
+ }
+ }
+
if (sDebug) Slog.d(TAG, "Good news, everyone! All checks passed, show save UI!");
mService.setSaveShown(id);
getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo,
@@ -1096,7 +1157,7 @@
}
}
- final ArrayList<Dataset> datasets = response.getDatasets();
+ final List<Dataset> datasets = response.getDatasets();
if (datasets != null) {
final int numDatasets = datasets.size();
@@ -1265,7 +1326,7 @@
// Only track the views of the last response as only those are reported back to the
// service, see #showSaveLocked
- final FillResponse response = mResponses.valueAt(getLastResponseIndex());
+ final FillResponse response = mResponses.valueAt(getLastResponseIndexLocked());
ArraySet<AutofillId> trackedViews = null;
boolean saveOnAllViewsInvisible = false;
@@ -1292,7 +1353,7 @@
// Must also track that are part of datasets, otherwise the FillUI won't be hidden when
// they go away (if they're not savable).
- final ArrayList<Dataset> datasets = response.getDatasets();
+ final List<Dataset> datasets = response.getDatasets();
ArraySet<AutofillId> fillableIds = null;
if (datasets != null) {
for (int i = 0; i < datasets.size(); i++) {
@@ -1365,7 +1426,7 @@
* Sets the state of all views in the given response.
*/
private void setViewStatesLocked(FillResponse response, int state, boolean clearResponse) {
- final ArrayList<Dataset> datasets = response.getDatasets();
+ final List<Dataset> datasets = response.getDatasets();
if (datasets != null) {
for (int i = 0; i < datasets.size(); i++) {
final Dataset dataset = datasets.get(i);
@@ -1642,17 +1703,19 @@
}
}
- private int getLastResponseIndex() {
+ private int getLastResponseIndexLocked() {
// The response ids are monotonically increasing so
// we just find the largest id which is the last. We
// do not rely on the internal ordering in sparse
// array to avoid - wow this stopped working!?
int lastResponseIdx = -1;
int lastResponseId = -1;
- final int responseCount = mResponses.size();
- for (int i = 0; i < responseCount; i++) {
- if (mResponses.keyAt(i) > lastResponseId) {
- lastResponseIdx = i;
+ if (mResponses != null) {
+ final int responseCount = mResponses.size();
+ for (int i = 0; i < responseCount; i++) {
+ if (mResponses.keyAt(i) > lastResponseId) {
+ lastResponseIdx = i;
+ }
}
}
return lastResponseIdx;
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index ddb621d..0351865 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -228,6 +228,7 @@
final WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
+ params.windowAnimations = R.style.AutofillSaveAnimation;
Slog.i(TAG, "Showing save dialog: " + mTitle);
mDialog.show();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 41de97c..cb4becc 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -776,7 +776,9 @@
// side unpredictability.
@Override
public int generateRandomIntegerToken() {
- int token = mTokenGenerator.nextInt() & ~0xFF;
+ int token = mTokenGenerator.nextInt();
+ if (token < 0) token = -token;
+ token &= ~0xFF;
token |= (mNextToken.incrementAndGet() & 0xFF);
return token;
}
@@ -1446,52 +1448,23 @@
// rebooted in the middle of an operation that was removing something from
// this log, we sanity-check its contents here and reconstruct it.
mEverStored = new File(mBaseStateDir, "processed");
- File tempProcessedFile = new File(mBaseStateDir, "processed.new");
-
- // If we were in the middle of removing something from the ever-backed-up
- // file, there might be a transient "processed.new" file still present.
- // Ignore it -- we'll validate "processed" against the current package set.
- if (tempProcessedFile.exists()) {
- tempProcessedFile.delete();
- }
// If there are previous contents, parse them out then start a new
// file to continue the recordkeeping.
if (mEverStored.exists()) {
- DataOutputStream temp = null;
- DataInputStream in = null;
-
- try {
- temp = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(
- tempProcessedFile)));
- in = new DataInputStream(new BufferedInputStream(new FileInputStream(mEverStored)));
+ try (DataInputStream in = new DataInputStream(
+ new BufferedInputStream(new FileInputStream(mEverStored)))) {
// Loop until we hit EOF
while (true) {
String pkg = in.readUTF();
- try {
- // is this package still present?
- mPackageManager.getPackageInfo(pkg, 0);
- // if we get here then yes it is; remember it
- mEverStoredApps.add(pkg);
- temp.writeUTF(pkg);
- if (MORE_DEBUG) Slog.v(TAG, " + " + pkg);
- } catch (NameNotFoundException e) {
- // nope, this package was uninstalled; don't include it
- if (MORE_DEBUG) Slog.v(TAG, " - " + pkg);
- }
+ mEverStoredApps.add(pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " + " + pkg);
}
} catch (EOFException e) {
- // Once we've rewritten the backup history log, atomically replace the
- // old one with the new one then reopen the file for continuing use.
- if (!tempProcessedFile.renameTo(mEverStored)) {
- Slog.e(TAG, "Error renaming " + tempProcessedFile + " to " + mEverStored);
- }
+ // Done
} catch (IOException e) {
Slog.e(TAG, "Error in processed file", e);
- } finally {
- try { if (temp != null) temp.close(); } catch (IOException e) {}
- try { if (in != null) in.close(); } catch (IOException e) {}
}
}
@@ -2238,44 +2211,6 @@
}
}
- // Remove our awareness of having ever backed up the given package
- void removeEverBackedUp(String packageName) {
- if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName);
- if (MORE_DEBUG) Slog.v(TAG, "New set:");
-
- synchronized (mEverStoredApps) {
- // Rewrite the file and rename to overwrite. If we reboot in the middle,
- // we'll recognize on initialization time that the package no longer
- // exists and fix it up then.
- File tempKnownFile = new File(mBaseStateDir, "processed.new");
- RandomAccessFile known = null;
- try {
- known = new RandomAccessFile(tempKnownFile, "rws");
- mEverStoredApps.remove(packageName);
- for (String s : mEverStoredApps) {
- known.writeUTF(s);
- if (MORE_DEBUG) Slog.v(TAG, " " + s);
- }
- known.close();
- known = null;
- if (!tempKnownFile.renameTo(mEverStored)) {
- throw new IOException("Can't rename " + tempKnownFile + " to " + mEverStored);
- }
- } catch (IOException e) {
- // Bad: we couldn't create the new copy. For safety's sake we
- // abandon the whole process and remove all what's-backed-up
- // state entirely, meaning we'll force a backup pass for every
- // participant on the next boot or [re]install.
- Slog.w(TAG, "Error rewriting " + mEverStored, e);
- mEverStoredApps.clear();
- tempKnownFile.delete();
- mEverStored.delete();
- } finally {
- try { if (known != null) known.close(); } catch (IOException e) {}
- }
- }
- }
-
// Persistently record the current and ancestral backup tokens as well
// as the set of packages with data [supposedly] available in the
// ancestral dataset.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 71c423c..ac41079 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4582,10 +4582,12 @@
*/
private void updateCapabilities(
int oldScore, NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) {
- if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities(
- networkCapabilities)) {
- Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: "
- + nai.networkCapabilities + " -> " + networkCapabilities);
+ // Sanity check: a NetworkAgent should not change its static capabilities or parameters.
+ if (nai.everConnected) {
+ String diff = nai.networkCapabilities.describeImmutableDifferences(networkCapabilities);
+ if (!TextUtils.isEmpty(diff)) {
+ Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities:" + diff);
+ }
}
// Don't modify caller's NetworkCapabilities.
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index b516a91..d3ce306 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -71,7 +71,7 @@
# when a notification action button has been clicked
27521 notification_action_clicked (key|3),(action_index|1),(lifespan|1),(freshness|1),(exposure|1)
# when a notification has been canceled
-27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1)
+27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1),(listener|3)
# replaces 27510 with a row per notification
27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1)
# a notification emited noise, vibration, or light
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index a8e2f32..c23757f 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -50,6 +50,7 @@
import org.xmlpull.v1.XmlSerializer;
import android.annotation.BinderThread;
+import android.annotation.ColorInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -213,8 +214,7 @@
Context.BIND_AUTO_CREATE
| Context.BIND_NOT_VISIBLE
| Context.BIND_NOT_FOREGROUND
- | Context.BIND_IMPORTANT_BACKGROUND
- | Context.BIND_SHOWING_UI;
+ | Context.BIND_IMPORTANT_BACKGROUND;
/**
* Binding flags used only while the {@link InputMethodService} is showing window.
@@ -222,7 +222,8 @@
private static final int IME_VISIBLE_BIND_FLAGS =
Context.BIND_AUTO_CREATE
| Context.BIND_TREAT_LIKE_ACTIVITY
- | Context.BIND_FOREGROUND_SERVICE;
+ | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_SHOWING_UI;
@Retention(SOURCE)
@IntDef({HardKeyboardBehavior.WIRELESS_AFFORDANCE, HardKeyboardBehavior.WIRED_AFFORDANCE})
@@ -231,6 +232,13 @@
int WIRED_AFFORDANCE = 1;
}
+ /**
+ * A protected broadcast intent action for internal use for {@link PendingIntent} in
+ * the notification.
+ */
+ private static final String ACTION_SHOW_INPUT_METHOD_PICKER =
+ "com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
+
final Context mContext;
final Resources mRes;
final Handler mHandler;
@@ -836,6 +844,16 @@
}
} else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
onActionLocaleChanged();
+ } else if (ACTION_SHOW_INPUT_METHOD_PICKER.equals(action)) {
+ // ACTION_SHOW_INPUT_METHOD_PICKER action is a protected-broadcast and it is
+ // guaranteed to be send only from the system, so that there is no need for extra
+ // security check such as
+ // {@link #canShowInputMethodPickerLocked(IInputMethodClient)}.
+ mHandler.obtainMessage(
+ MSG_SHOW_IM_SUBTYPE_PICKER,
+ InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES,
+ 0 /* arg2 */)
+ .sendToTarget();
} else {
Slog.w(TAG, "Unexpected intent " + intent);
}
@@ -1285,6 +1303,8 @@
Bundle extras = new Bundle();
extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
+ @ColorInt final int accentColor = mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color);
mImeSwitcherNotification =
new Notification.Builder(mContext, SystemNotificationChannels.VIRTUAL_KEYBOARD)
.setSmallIcon(com.android.internal.R.drawable.ic_notification_ime_default)
@@ -1292,9 +1312,10 @@
.setOngoing(true)
.addExtras(extras)
.setCategory(Notification.CATEGORY_SYSTEM)
- .setColor(com.android.internal.R.color.system_notification_accent_color);
+ .setColor(accentColor);
- Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
+ Intent intent = new Intent(ACTION_SHOW_INPUT_METHOD_PICKER)
+ .setPackage(mContext.getPackageName());
mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
mShowOngoingImeSwitcherForPhones = false;
@@ -1445,6 +1466,7 @@
broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
broadcastFilter.addAction(Intent.ACTION_SETTING_RESTORED);
broadcastFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
+ broadcastFilter.addAction(ACTION_SHOW_INPUT_METHOD_PICKER);
mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);
buildInputMethodListLocked(true /* resetDefaultEnabledIme */);
@@ -2088,7 +2110,8 @@
private boolean shouldShowImeSwitcherLocked(int visibility) {
if (!mShowOngoingImeSwitcherForPhones) return false;
if (mSwitchingDialog != null) return false;
- if (isScreenLocked()) return false;
+ if (mWindowManagerInternal.isKeyguardShowingAndNotOccluded()
+ && mKeyguardManager != null && mKeyguardManager.isKeyguardSecure()) return false;
if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false;
if (mWindowManagerInternal.isHardKeyboardAvailable()) {
if (mHardKeyboardBehavior == HardKeyboardBehavior.WIRELESS_AFFORDANCE) {
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index fdc0bba..d60df83 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -27,6 +27,7 @@
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
+import android.location.LocationManager;
import android.net.INetworkRecommendationProvider;
import android.net.INetworkScoreCache;
import android.net.INetworkScoreService;
@@ -113,6 +114,16 @@
}
};
+ private BroadcastReceiver mLocationModeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
+ refreshBinding();
+ }
+ }
+ };
+
/**
* Clears scores when the active scorer package is no longer valid and
* manages the service connection.
@@ -241,6 +252,10 @@
mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/,
null /* scheduler */);
mHandler = new ServiceHandler(looper);
+ IntentFilter locationModeFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
+ mContext.registerReceiverAsUser(
+ mLocationModeReceiver, UserHandle.SYSTEM, locationModeFilter,
+ null /* broadcastPermission*/, mHandler);
mContentObserver = new DispatchingContentObserver(context, mHandler);
mServiceConnProducer = serviceConnProducer;
}
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 42777bf..bfd4247 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -18,6 +18,7 @@
import android.Manifest.permission;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -79,7 +80,7 @@
List<NetworkScorerAppData> appDataList = new ArrayList<>();
for (int i = 0; i < resolveInfos.size(); i++) {
final ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo;
- if (hasPermissions(serviceInfo.packageName)) {
+ if (hasPermissions(serviceInfo.applicationInfo.uid, serviceInfo.packageName)) {
if (VERBOSE) {
Log.v(TAG, serviceInfo.packageName + " is a valid scorer/recommender.");
}
@@ -197,12 +198,33 @@
return null;
}
- private boolean hasPermissions(String packageName) {
+ private boolean hasPermissions(final int uid, final String packageName) {
+ return hasScoreNetworksPermission(packageName)
+ && canAccessLocation(uid, packageName);
+ }
+
+ private boolean hasScoreNetworksPermission(String packageName) {
final PackageManager pm = mContext.getPackageManager();
return pm.checkPermission(permission.SCORE_NETWORKS, packageName)
== PackageManager.PERMISSION_GRANTED;
}
+ private boolean canAccessLocation(int uid, String packageName) {
+ final PackageManager pm = mContext.getPackageManager();
+ final AppOpsManager appOpsManager =
+ (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+ return isLocationModeEnabled()
+ && pm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName)
+ == PackageManager.PERMISSION_GRANTED
+ && appOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName)
+ == AppOpsManager.MODE_ALLOWED;
+ }
+
+ private boolean isLocationModeEnabled() {
+ return mSettingsFacade.getSecureInt(mContext, Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF;
+ }
+
/**
* Set the specified package as the default scorer application.
*
@@ -270,23 +292,20 @@
return;
}
- // the active scorer isn't valid, revert to the default if it's different
+ int newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF;
+ // the active scorer isn't valid, revert to the default if it's different and valid
final String defaultPackageName = getDefaultPackageSetting();
- if (!TextUtils.equals(currentPackageName, defaultPackageName)) {
- setNetworkRecommendationsPackage(defaultPackageName);
+ if (!TextUtils.equals(currentPackageName, defaultPackageName)
+ && getScorer(defaultPackageName) != null) {
if (DEBUG) {
- Log.d(TAG, "Defaulted the network recommendations app to: " + defaultPackageName);
+ Log.d(TAG, "Defaulting the network recommendations app to: "
+ + defaultPackageName);
}
- if (getScorer(defaultPackageName) != null) { // the default is valid
- if (DEBUG) Log.d(TAG, defaultPackageName + " is now the active scorer.");
- setNetworkRecommendationsEnabledSetting(
- NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON);
- } else { // the default isn't valid either, we're disabled at this point
- if (DEBUG) Log.d(TAG, defaultPackageName + " is not an active scorer.");
- setNetworkRecommendationsEnabledSetting(
- NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF);
- }
+ setNetworkRecommendationsPackage(defaultPackageName);
+ newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON;
}
+
+ setNetworkRecommendationsEnabledSetting(newEnabledSetting);
}
/**
@@ -352,6 +371,9 @@
private void setNetworkRecommendationsPackage(String packageName) {
mSettingsFacade.putString(mContext,
Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, packageName);
+ if (VERBOSE) {
+ Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE + " set to " + packageName);
+ }
}
private int getNetworkRecommendationsEnabledSetting() {
@@ -361,6 +383,9 @@
private void setNetworkRecommendationsEnabledSetting(int value) {
mSettingsFacade.putInt(mContext,
Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, value);
+ if (VERBOSE) {
+ Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED + " set to " + value);
+ }
}
/**
@@ -382,5 +407,9 @@
public int getInt(Context context, String name, int defaultValue) {
return Settings.Global.getInt(context.getContentResolver(), name, defaultValue);
}
+
+ public int getSecureInt(Context context, String name, int defaultValue) {
+ return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue);
+ }
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index aa2ce1c..1ca0112 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2969,6 +2969,11 @@
synchronized (mLock) {
mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
}
+ if (userId == UserHandle.USER_SYSTEM) {
+ String propertyName = "sys.user." + userId + ".ce_available";
+ Slog.d(TAG, "Setting property: " + propertyName + "=true");
+ SystemProperties.set(propertyName, "true");
+ }
}
@Override
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 80d39f5..c297010 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -370,7 +370,7 @@
private void unbindServiceLocked() {
for (SpellCheckerBindGroup scbg : mSpellCheckerBindGroups.values()) {
- scbg.removeAll();
+ scbg.removeAllLocked();
}
mSpellCheckerBindGroups.clear();
}
@@ -598,7 +598,7 @@
Slog.w(TAG, "bind service: " + info.getId());
}
if (!bindCurrentSpellCheckerService(serviceIntent, connection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) {
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT_BACKGROUND)) {
Slog.e(TAG, "Failed to get a spell checker service.");
return null;
}
@@ -788,29 +788,41 @@
mListeners = new InternalDeathRecipients(this);
}
- public void onServiceConnected(ISpellCheckerService spellChecker) {
+ public void onServiceConnectedLocked(ISpellCheckerService spellChecker) {
if (DBG) {
- Slog.d(TAG, "onServiceConnected");
+ Slog.d(TAG, "onServiceConnectedLocked");
}
- synchronized (mLock) {
- mSpellChecker = spellChecker;
- mConnected = true;
- // Dispatch pending getISpellCheckerSession requests.
- mPendingSessionRequests.forEach(this::getISpellCheckerSessionLocked);
- mPendingSessionRequests.clear();
+ if (mUnbindCalled) {
+ return;
}
+ mSpellChecker = spellChecker;
+ mConnected = true;
+ // Dispatch pending getISpellCheckerSession requests.
+ try {
+ final int size = mPendingSessionRequests.size();
+ for (int i = 0; i < size; ++i) {
+ final SessionRequest request = mPendingSessionRequests.get(i);
+ mSpellChecker.getISpellCheckerSession(
+ request.mLocale, request.mScListener, request.mBundle,
+ new ISpellCheckerServiceCallbackBinder(this, request));
+ mOnGoingSessionRequests.add(request);
+ }
+ mPendingSessionRequests.clear();
+ } catch(RemoteException e) {
+ // The target spell checker service is not available. Better to reset the state.
+ removeAllLocked();
+ }
+ cleanLocked();
}
- public void onServiceDisconnected() {
+ public void onServiceDisconnectedLocked() {
if (DBG) {
- Slog.d(TAG, "onServiceDisconnected");
+ Slog.d(TAG, "onServiceDisconnectedLocked");
}
- synchronized (mLock) {
- mSpellChecker = null;
- mConnected = false;
- }
+ mSpellChecker = null;
+ mConnected = false;
}
public void removeListener(ISpellCheckerSessionListener listener) {
@@ -853,17 +865,15 @@
mUnbindCalled = true;
}
- public void removeAll() {
+ public void removeAllLocked() {
Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
- synchronized (mLock) {
- final int size = mListeners.getRegisteredCallbackCount();
- for (int i = size - 1; i >= 0; --i) {
- mListeners.unregister(mListeners.getRegisteredCallbackItem(i));
- }
- mPendingSessionRequests.clear();
- mOnGoingSessionRequests.clear();
- cleanLocked();
+ final int size = mListeners.getRegisteredCallbackCount();
+ for (int i = size - 1; i >= 0; --i) {
+ mListeners.unregister(mListeners.getRegisteredCallbackItem(i));
}
+ mPendingSessionRequests.clear();
+ mOnGoingSessionRequests.clear();
+ cleanLocked();
}
public void getISpellCheckerSessionOrQueueLocked(@NonNull SessionRequest request) {
@@ -874,13 +884,6 @@
mPendingSessionRequests.add(request);
return;
}
- getISpellCheckerSessionLocked(request);
- }
-
- private void getISpellCheckerSessionLocked(@NonNull SessionRequest request) {
- if (mUnbindCalled) {
- return;
- }
try {
mSpellChecker.getISpellCheckerSession(
request.mLocale, request.mScListener, request.mBundle,
@@ -888,7 +891,7 @@
mOnGoingSessionRequests.add(request);
} catch(RemoteException e) {
// The target spell checker service is not available. Better to reset the state.
- removeAll();
+ removeAllLocked();
}
cleanLocked();
}
@@ -930,13 +933,13 @@
private void onServiceConnectedInnerLocked(ComponentName name, IBinder service) {
if (DBG) {
- Slog.w(TAG, "onServiceConnected: " + name);
+ Slog.w(TAG, "onServiceConnectedInnerLocked: " + name);
}
final ISpellCheckerService spellChecker =
ISpellCheckerService.Stub.asInterface(service);
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
if (group != null && this == group.mInternalConnection) {
- group.onServiceConnected(spellChecker);
+ group.onServiceConnectedLocked(spellChecker);
}
}
@@ -949,11 +952,11 @@
private void onServiceDisconnectedInnerLocked(ComponentName name) {
if (DBG) {
- Slog.w(TAG, "onServiceDisconnected: " + name);
+ Slog.w(TAG, "onServiceDisconnectedInnerLocked: " + name);
}
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
if (group != null && this == group.mInternalConnection) {
- group.onServiceDisconnected();
+ group.onServiceDisconnectedLocked();
}
}
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 6a81d32..8d46d1e 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -18,7 +18,11 @@
import android.app.IActivityController;
import android.os.Binder;
+import android.os.Build;
import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.system.StructRlimit;
import com.android.internal.os.ZygoteConnectionConstants;
import com.android.server.am.ActivityManagerService;
@@ -45,6 +49,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -107,6 +112,7 @@
int mPhonePid;
IActivityController mController;
boolean mAllowRestart = true;
+ final OpenFdMonitor mOpenFdMonitor;
/**
* Used for checking status of handle threads and scheduling monitor callbacks.
@@ -269,6 +275,8 @@
// Initialize monitor for Binder threads.
addMonitor(new BinderThreadMonitor());
+ mOpenFdMonitor = OpenFdMonitor.create();
+
// See the notes on DEFAULT_TIMEOUT.
assert DB ||
DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
@@ -358,7 +366,7 @@
return checkers;
}
- private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
+ private String describeCheckersLocked(List<HandlerChecker> checkers) {
StringBuilder builder = new StringBuilder(128);
for (int i=0; i<checkers.size(); i++) {
if (builder.length() > 0) {
@@ -410,7 +418,7 @@
public void run() {
boolean waitedHalf = false;
while (true) {
- final ArrayList<HandlerChecker> blockedCheckers;
+ final List<HandlerChecker> blockedCheckers;
final String subject;
final boolean allowRestart;
int debuggerWasConnected = 0;
@@ -447,30 +455,40 @@
timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
}
- final int waitState = evaluateCheckerCompletionLocked();
- if (waitState == COMPLETED) {
- // The monitors have returned; reset
- waitedHalf = false;
- continue;
- } else if (waitState == WAITING) {
- // still waiting but within their configured intervals; back off and recheck
- continue;
- } else if (waitState == WAITED_HALF) {
- if (!waitedHalf) {
- // We've waited half the deadlock-detection interval. Pull a stack
- // trace and wait another half.
- ArrayList<Integer> pids = new ArrayList<Integer>();
- pids.add(Process.myPid());
- ActivityManagerService.dumpStackTraces(true, pids, null, null,
- getInterestingNativePids());
- waitedHalf = true;
- }
- continue;
+ boolean fdLimitTriggered = false;
+ if (mOpenFdMonitor != null) {
+ fdLimitTriggered = mOpenFdMonitor.monitor();
}
- // something is overdue!
- blockedCheckers = getBlockedCheckersLocked();
- subject = describeCheckersLocked(blockedCheckers);
+ if (!fdLimitTriggered) {
+ final int waitState = evaluateCheckerCompletionLocked();
+ if (waitState == COMPLETED) {
+ // The monitors have returned; reset
+ waitedHalf = false;
+ continue;
+ } else if (waitState == WAITING) {
+ // still waiting but within their configured intervals; back off and recheck
+ continue;
+ } else if (waitState == WAITED_HALF) {
+ if (!waitedHalf) {
+ // We've waited half the deadlock-detection interval. Pull a stack
+ // trace and wait another half.
+ ArrayList<Integer> pids = new ArrayList<Integer>();
+ pids.add(Process.myPid());
+ ActivityManagerService.dumpStackTraces(true, pids, null, null,
+ getInterestingNativePids());
+ waitedHalf = true;
+ }
+ continue;
+ }
+
+ // something is overdue!
+ blockedCheckers = getBlockedCheckersLocked();
+ subject = describeCheckersLocked(blockedCheckers);
+ } else {
+ blockedCheckers = Collections.emptyList();
+ subject = "Open FD high water mark reached";
+ }
allowRestart = mAllowRestart;
}
@@ -584,4 +602,87 @@
}
private native void native_dumpKernelStacks(String tracesPath);
+
+ public static final class OpenFdMonitor {
+ /**
+ * Number of FDs below the soft limit that we trigger a runtime restart at. This was
+ * chosen arbitrarily, but will need to be at least 6 in order to have a sufficient number
+ * of FDs in reserve to complete a dump.
+ */
+ private static final int FD_HIGH_WATER_MARK = 12;
+
+ private final File mDumpDir;
+ private final File mFdHighWaterMark;
+
+ public static OpenFdMonitor create() {
+ // Only run the FD monitor on debuggable builds (such as userdebug and eng builds).
+ if (!Build.IS_DEBUGGABLE) {
+ return null;
+ }
+
+ // Don't run the FD monitor on builds that have a global ANR trace file. We're using
+ // the ANR trace directory as a quick hack in order to get these traces in bugreports
+ // and we wouldn't want to overwrite something important.
+ final String dumpDirStr = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
+ if (dumpDirStr.isEmpty()) {
+ return null;
+ }
+
+ final StructRlimit rlimit;
+ try {
+ rlimit = android.system.Os.getrlimit(OsConstants.RLIMIT_NOFILE);
+ } catch (ErrnoException errno) {
+ Slog.w(TAG, "Error thrown from getrlimit(RLIMIT_NOFILE)", errno);
+ return null;
+ }
+
+ // The assumption we're making here is that FD numbers are allocated (more or less)
+ // sequentially, which is currently (and historically) true since open is currently
+ // specified to always return the lowest-numbered non-open file descriptor for the
+ // current process.
+ //
+ // We do this to avoid having to enumerate the contents of /proc/self/fd in order to
+ // count the number of descriptors open in the process.
+ final File fdThreshold = new File("/proc/self/fd/" + (rlimit.rlim_cur - FD_HIGH_WATER_MARK));
+ return new OpenFdMonitor(new File(dumpDirStr), fdThreshold);
+ }
+
+ OpenFdMonitor(File dumpDir, File fdThreshold) {
+ mDumpDir = dumpDir;
+ mFdHighWaterMark = fdThreshold;
+ }
+
+ private void dumpOpenDescriptors() {
+ try {
+ File dumpFile = File.createTempFile("anr_fd_", "", mDumpDir);
+ java.lang.Process proc = new ProcessBuilder()
+ .command("/system/bin/lsof", "-p", String.valueOf(Process.myPid()))
+ .redirectErrorStream(true)
+ .redirectOutput(dumpFile)
+ .start();
+
+ int returnCode = proc.waitFor();
+ if (returnCode != 0) {
+ Slog.w(TAG, "Unable to dump open descriptors, lsof return code: "
+ + returnCode);
+ dumpFile.delete();
+ }
+ } catch (IOException | InterruptedException ex) {
+ Slog.w(TAG, "Unable to dump open descriptors: " + ex);
+ }
+ }
+
+ /**
+ * @return {@code true} if the high water mark was breached and a dump was written,
+ * {@code false} otherwise.
+ */
+ public boolean monitor() {
+ if (mFdHighWaterMark.exists()) {
+ dumpOpenDescriptors();
+ return true;
+ }
+
+ return false;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1281fb1..161bf9a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -714,7 +714,9 @@
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
- && !mKeyguardController.isKeyguardShowing();
+ && !mKeyguardController.isKeyguardShowing()
+ && !(UserManager.isDeviceInDemoMode(mContext)
+ && mUserController.getCurrentUser().isDemo());
}
private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
@@ -14978,7 +14980,7 @@
}
} else if ("starter".equals(cmd)) {
synchronized (this) {
- dumpActivityStarterLocked(pw);
+ dumpActivityStarterLocked(pw, dumpPackage);
}
} else if ("recents".equals(cmd) || "r".equals(cmd)) {
synchronized (this) {
@@ -15213,7 +15215,7 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpActivityStarterLocked(pw);
+ dumpActivityStarterLocked(pw, dumpPackage);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
@@ -15283,7 +15285,7 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpActivityStarterLocked(pw);
+ dumpActivityStarterLocked(pw, dumpPackage);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
@@ -15307,7 +15309,7 @@
}
private void dumpLastANRLocked(PrintWriter pw) {
- pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
+ pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
if (mLastANRState == null) {
pw.println(" <no ANR has occurred since boot>");
} else {
@@ -15315,9 +15317,9 @@
}
}
- private void dumpActivityStarterLocked(PrintWriter pw) {
- pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
- mActivityStarter.dump(pw, "");
+ private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
+ pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
+ mActivityStarter.dump(pw, "", dumpPackage);
}
void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
@@ -22818,11 +22820,11 @@
uidRec.lastBackgroundTime = 0;
}
final boolean wasCached = uidRec.setProcState
- > ActivityManager.PROCESS_STATE_RECEIVER && uidRec.setProcState
- != ActivityManager.PROCESS_STATE_NONEXISTENT;
+ > ActivityManager.PROCESS_STATE_RECEIVER;
final boolean isCached = uidRec.curProcState
> ActivityManager.PROCESS_STATE_RECEIVER;
- if (wasCached != isCached) {
+ if (wasCached != isCached ||
+ uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
}
uidRec.setProcState = uidRec.curProcState;
@@ -23879,7 +23881,9 @@
Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
return;
}
- ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+ synchronized (ActivityManagerService.this) {
+ ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+ }
}
@Override
@@ -24081,7 +24085,7 @@
pw.println(" Reason: " + reason);
}
pw.println();
- mActivityStarter.dump(pw, " ");
+ mActivityStarter.dump(pw, " ", null);
pw.println();
pw.println("-------------------------------------------------------------------------------");
dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 3c84941..7a19cc3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -41,9 +41,7 @@
import static android.content.Intent.CATEGORY_LAUNCHER;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
-import static android.content.pm.ActivityInfo.CONFIG_APP_BOUNDS;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_ROTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
@@ -429,11 +427,11 @@
pw.print("\"");
pw.print(" primaryColor=");
pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
- pw.print(prefix + " backgroundColor=");
+ pw.print(prefix); pw.print(" backgroundColor=");
pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
- pw.print(prefix + " statusBarColor=");
+ pw.print(prefix); pw.print(" statusBarColor=");
pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
- pw.print(prefix + " navigationBarColor=");
+ pw.print(prefix); pw.print(" navigationBarColor=");
pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
}
if (iconFilename == null && taskDescription.getIcon() != null) {
@@ -2163,7 +2161,7 @@
if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
mStartingWindowState = STARTING_WINDOW_REMOVED;
- mWindowContainerController.removeHiddenStartingWindow();
+ mWindowContainerController.removeStartingWindow();
}
}
@@ -2573,15 +2571,6 @@
changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
}
}
- // We don't want rotation to cause relaunches.
- if ((changes & CONFIG_ROTATION) != 0) {
- changes &= ~CONFIG_ROTATION;
- }
-
- // We don't want app bound changes to cause relaunches.
- if ((changes & CONFIG_APP_BOUNDS) != 0) {
- changes &= ~CONFIG_APP_BOUNDS;
- }
return changes;
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9925ba0..79448ca 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -650,6 +650,13 @@
return topRunningActivityLocked(false /* focusableOnly */);
}
+ void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+ outActivities.clear();
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities);
+ }
+ }
+
private ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 5f42cdb..e8bc68f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -441,6 +441,8 @@
final ActivityMetricsLogger mActivityMetricsLogger;
+ private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
+
@Override
protected int getChildCount() {
return mActivityDisplays.size();
@@ -954,17 +956,21 @@
if (!isFocusedStack(stack)) {
continue;
}
- ActivityRecord hr = stack.topRunningActivityLocked();
- if (hr != null) {
- if (hr.app == null && app.uid == hr.info.applicationInfo.uid
- && processName.equals(hr.processName)) {
+ stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
+ final ActivityRecord top = stack.topRunningActivityLocked();
+ final int size = mTmpActivityList.size();
+ for (int i = 0; i < size; i++) {
+ final ActivityRecord activity = mTmpActivityList.get(i);
+ if (activity.app == null && app.uid == activity.info.applicationInfo.uid
+ && processName.equals(activity.processName)) {
try {
- if (realStartActivityLocked(hr, app, true, true)) {
+ if (realStartActivityLocked(activity, app,
+ top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
- + hr.intent.getComponent().flattenToShortString(), e);
+ + top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 0931587..6544593 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -581,8 +581,8 @@
Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE, originalIntent,
auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
resolvedType, userId, auxiliaryResponse.packageName, auxiliaryResponse.splitName,
- auxiliaryResponse.versionCode, auxiliaryResponse.token,
- auxiliaryResponse.needsPhaseTwo);
+ auxiliaryResponse.installFailureActivity, auxiliaryResponse.versionCode,
+ auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
}
void postStartActivityProcessing(
@@ -2306,40 +2306,76 @@
return didSomething;
}
- void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "ActivityStarter:");
+ void dump(PrintWriter pw, String prefix, String dumpPackage) {
prefix = prefix + " ";
- pw.println(prefix + "mCurrentUser=" + mSupervisor.mCurrentUser);
- pw.println(prefix + "mLastStartReason=" + mLastStartReason);
- pw.println(prefix + "mLastStartActivityTimeMs="
- + DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
- pw.println(prefix + "mLastStartActivityResult=" + mLastStartActivityResult);
+ if (dumpPackage != null) {
+ if ((mLastStartActivityRecord[0] == null ||
+ !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) &&
+ (mLastHomeActivityStartRecord[0] == null ||
+ !dumpPackage.equals(mLastHomeActivityStartRecord[0].packageName)) &&
+ (mStartActivity == null || !dumpPackage.equals(mStartActivity.packageName))) {
+ pw.print(prefix);
+ pw.println("(nothing)");
+ return;
+ }
+ }
+
+ pw.print(prefix);
+ pw.print("mCurrentUser=");
+ pw.println(mSupervisor.mCurrentUser);
+ pw.print(prefix);
+ pw.print("mLastStartReason=");
+ pw.println(mLastStartReason);
+ pw.print(prefix);
+ pw.print("mLastStartActivityTimeMs=");
+ pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
+ pw.print(prefix);
+ pw.print("mLastStartActivityResult=");
+ pw.println(mLastStartActivityResult);
ActivityRecord r = mLastStartActivityRecord[0];
if (r != null) {
- pw.println(prefix + "mLastStartActivityRecord:");
- r.dump(pw, prefix + " ");
+ pw.print(prefix);
+ pw.println("mLastStartActivityRecord:");
+ r.dump(pw, prefix + " ");
}
- pw.println(prefix + "mLastHomeActivityStartResult=" + mLastHomeActivityStartResult);
+ pw.print(prefix);
+ pw.print("mLastHomeActivityStartResult=");
+ pw.println(mLastHomeActivityStartResult);
r = mLastHomeActivityStartRecord[0];
if (r != null) {
- pw.println(prefix + "mLastHomeActivityStartRecord:");
- r.dump(pw, prefix + " ");
+ pw.print(prefix);
+ pw.println("mLastHomeActivityStartRecord:");
+ r.dump(pw, prefix + " ");
}
if (mStartActivity != null) {
- pw.println(prefix + "mStartActivity:");
- mStartActivity.dump(pw, prefix + " ");
+ pw.print(prefix);
+ pw.println("mStartActivity:");
+ mStartActivity.dump(pw, prefix + " ");
}
if (mIntent != null) {
- pw.println(prefix + "mIntent=" + mIntent);
+ pw.print(prefix);
+ pw.print("mIntent=");
+ pw.println(mIntent);
}
if (mOptions != null) {
- pw.println(prefix + "mOptions=" + mOptions);
+ pw.print(prefix);
+ pw.print("mOptions=");
+ pw.println(mOptions);
}
- pw.println(prefix + "mLaunchSingleTop=" + mLaunchSingleTop
- + " mLaunchSingleInstance=" + mLaunchSingleInstance
- + " mLaunchSingleTask=" + mLaunchSingleTask
- + " mLaunchFlags=0x" + Integer.toHexString(mLaunchFlags)
- + " mDoResume=" + mDoResume + " mAddingToTask=" + mAddingToTask);
+ pw.print(prefix);
+ pw.print("mLaunchSingleTop=");
+ pw.print(mLaunchSingleTop);
+ pw.print(" mLaunchSingleInstance=");
+ pw.print(mLaunchSingleInstance);
+ pw.print(" mLaunchSingleTask=");
+ pw.println(mLaunchSingleTask);
+ pw.print(prefix);
+ pw.print("mLaunchFlags=0x");
+ pw.print(Integer.toHexString(mLaunchFlags));
+ pw.print(" mDoResume=");
+ pw.print(mDoResume);
+ pw.print(" mAddingToTask=");
+ pw.println(mAddingToTask);
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 739497b..7c7eda7 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -802,7 +802,7 @@
IPackageManager pm = AppGlobals.getPackageManager();
for (int i = perms.length-1; i >= 0; i--) {
try {
- PermissionInfo pi = pm.getPermissionInfo(perms[i], 0);
+ PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
| PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
!= PermissionInfo.PROTECTION_SIGNATURE) {
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index e56b09d..74c4826 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -679,102 +679,111 @@
}
writeTaskIdsFiles();
- // If mNextWriteTime, then don't delay between each call to saveToXml().
- final WriteQueueItem item;
- synchronized (TaskPersister.this) {
- if (mNextWriteTime != FLUSH_QUEUE) {
- // The next write we don't have to wait so long.
- mNextWriteTime = SystemClock.uptimeMillis() + INTER_WRITE_DELAY_MS;
- if (DEBUG) Slog.d(TAG, "Next write time may be in " +
- INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")");
- }
+ processNextItem();
+ }
+ }
- while (mWriteQueue.isEmpty()) {
- if (mNextWriteTime != 0) {
- mNextWriteTime = 0; // idle.
- TaskPersister.this.notifyAll(); // wake up flush() if needed.
- }
- try {
- if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
- TaskPersister.this.wait();
- } catch (InterruptedException e) {
- }
- // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
- // from now.
- }
- item = mWriteQueue.remove(0);
+ private void processNextItem() {
+ // This part is extracted into a method so that the GC can clearly see the end of the
+ // scope of the variable 'item'. If this part was in the loop above, the last item
+ // it processed would always "leak".
+ // See https://b.corp.google.com/issues/64438652#comment7
- long now = SystemClock.uptimeMillis();
- if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
- mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
- while (now < mNextWriteTime) {
- try {
- if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
- (mNextWriteTime - now));
- TaskPersister.this.wait(mNextWriteTime - now);
- } catch (InterruptedException e) {
- }
- now = SystemClock.uptimeMillis();
- }
-
- // Got something to do.
+ // If mNextWriteTime, then don't delay between each call to saveToXml().
+ final WriteQueueItem item;
+ synchronized (TaskPersister.this) {
+ if (mNextWriteTime != FLUSH_QUEUE) {
+ // The next write we don't have to wait so long.
+ mNextWriteTime = SystemClock.uptimeMillis() + INTER_WRITE_DELAY_MS;
+ if (DEBUG) Slog.d(TAG, "Next write time may be in " +
+ INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")");
}
- if (item instanceof ImageWriteQueueItem) {
- ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
- final String filePath = imageWriteQueueItem.mFilePath;
- if (!createParentDirectory(filePath)) {
- Slog.e(TAG, "Error while creating images directory for file: " + filePath);
- continue;
+ while (mWriteQueue.isEmpty()) {
+ if (mNextWriteTime != 0) {
+ mNextWriteTime = 0; // idle.
+ TaskPersister.this.notifyAll(); // wake up flush() if needed.
}
- final Bitmap bitmap = imageWriteQueueItem.mImage;
- if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath);
- FileOutputStream imageFile = null;
try {
- imageFile = new FileOutputStream(new File(filePath));
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageFile);
- } catch (Exception e) {
- Slog.e(TAG, "saveImage: unable to save " + filePath, e);
- } finally {
- IoUtils.closeQuietly(imageFile);
+ if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
+ TaskPersister.this.wait();
+ } catch (InterruptedException e) {
}
- } else if (item instanceof TaskWriteQueueItem) {
- // Write out one task.
- StringWriter stringWriter = null;
- TaskRecord task = ((TaskWriteQueueItem) item).mTask;
- if (DEBUG) Slog.d(TAG, "Writing task=" + task);
- synchronized (mService) {
- if (task.inRecents) {
- // Still there.
- try {
- if (DEBUG) Slog.d(TAG, "Saving task=" + task);
- stringWriter = saveToXml(task);
- } catch (IOException e) {
- } catch (XmlPullParserException e) {
- }
- }
+ // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
+ // from now.
+ }
+ item = mWriteQueue.remove(0);
+
+ long now = SystemClock.uptimeMillis();
+ if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
+ mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
+ while (now < mNextWriteTime) {
+ try {
+ if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
+ (mNextWriteTime - now));
+ TaskPersister.this.wait(mNextWriteTime - now);
+ } catch (InterruptedException e) {
}
- if (stringWriter != null) {
- // Write out xml file while not holding mService lock.
- FileOutputStream file = null;
- AtomicFile atomicFile = null;
+ now = SystemClock.uptimeMillis();
+ }
+
+ // Got something to do.
+ }
+
+ if (item instanceof ImageWriteQueueItem) {
+ ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
+ final String filePath = imageWriteQueueItem.mFilePath;
+ if (!createParentDirectory(filePath)) {
+ Slog.e(TAG, "Error while creating images directory for file: " + filePath);
+ return;
+ }
+ final Bitmap bitmap = imageWriteQueueItem.mImage;
+ if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath);
+ FileOutputStream imageFile = null;
+ try {
+ imageFile = new FileOutputStream(new File(filePath));
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageFile);
+ } catch (Exception e) {
+ Slog.e(TAG, "saveImage: unable to save " + filePath, e);
+ } finally {
+ IoUtils.closeQuietly(imageFile);
+ }
+ } else if (item instanceof TaskWriteQueueItem) {
+ // Write out one task.
+ StringWriter stringWriter = null;
+ TaskRecord task = ((TaskWriteQueueItem) item).mTask;
+ if (DEBUG) Slog.d(TAG, "Writing task=" + task);
+ synchronized (mService) {
+ if (task.inRecents) {
+ // Still there.
try {
- atomicFile = new AtomicFile(new File(
- getUserTasksDir(task.userId),
- String.valueOf(task.taskId) + TASK_FILENAME_SUFFIX));
- file = atomicFile.startWrite();
- file.write(stringWriter.toString().getBytes());
- file.write('\n');
- atomicFile.finishWrite(file);
+ if (DEBUG) Slog.d(TAG, "Saving task=" + task);
+ stringWriter = saveToXml(task);
} catch (IOException e) {
- if (file != null) {
- atomicFile.failWrite(file);
- }
- Slog.e(TAG,
- "Unable to open " + atomicFile + " for persisting. " + e);
+ } catch (XmlPullParserException e) {
}
}
}
+ if (stringWriter != null) {
+ // Write out xml file while not holding mService lock.
+ FileOutputStream file = null;
+ AtomicFile atomicFile = null;
+ try {
+ atomicFile = new AtomicFile(new File(
+ getUserTasksDir(task.userId),
+ String.valueOf(task.taskId) + TASK_FILENAME_SUFFIX));
+ file = atomicFile.startWrite();
+ file.write(stringWriter.toString().getBytes());
+ file.write('\n');
+ atomicFile.finishWrite(file);
+ } catch (IOException e) {
+ if (file != null) {
+ atomicFile.failWrite(file);
+ }
+ Slog.e(TAG,
+ "Unable to open " + atomicFile + " for persisting. " + e);
+ }
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5753fbc..88d8944 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1159,6 +1159,17 @@
return null;
}
+ void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+ if (mStack != null) {
+ for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+ ActivityRecord r = mActivities.get(activityNdx);
+ if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
+ outActivities.add(r);
+ }
+ }
+ }
+ }
+
ActivityRecord topRunningActivityWithStartingWindowLocked() {
if (mStack != null) {
for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 405ee32..ceae82f 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -671,12 +671,6 @@
}
if (stopped) {
- // Evict the user's credential encryption key
- try {
- getStorageManager().lockUserKey(userId);
- } catch (RemoteException re) {
- throw re.rethrowAsRuntimeException();
- }
mInjector.systemServiceManagerCleanupUser(userId);
synchronized (mLock) {
mInjector.getActivityStackSupervisor().removeUserLocked(userId);
@@ -685,6 +679,12 @@
if (getUserInfo(userId).isEphemeral()) {
mInjector.getUserManager().removeUser(userId);
}
+ // Evict the user's credential encryption key.
+ try {
+ getStorageManager().lockUserKey(userId);
+ } catch (RemoteException re) {
+ throw re.rethrowAsRuntimeException();
+ }
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/Convert.java b/services/core/java/com/android/server/broadcastradio/Convert.java
new file mode 100644
index 0000000..125554f
--- /dev/null
+++ b/services/core/java/com/android/server/broadcastradio/Convert.java
@@ -0,0 +1,59 @@
+/**
+ * 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.broadcastradio;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Slog;
+
+import java.util.Map;
+import java.util.Set;
+
+class Convert {
+ private static final String TAG = "BroadcastRadioService.Convert";
+
+ /**
+ * Converts string map to an array that's easily accessible by native code.
+ *
+ * Calling this java method once is more efficient than converting map object on the native
+ * side, which requires several separate java calls for each element.
+ *
+ * @param map map to convert.
+ * @returns array (sized the same as map) of two-element string arrays
+ * (first element is the key, second is value).
+ */
+ static @NonNull String[][] stringMapToNative(@Nullable Map<String, String> map) {
+ if (map == null) {
+ Slog.v(TAG, "map is null, returning zero-elements array");
+ return new String[0][0];
+ }
+
+ Set<Map.Entry<String, String>> entries = map.entrySet();
+ int len = entries.size();
+ String[][] arr = new String[len][2];
+
+ int i = 0;
+ for (Map.Entry<String, String> entry : entries) {
+ arr[i][0] = entry.getKey();
+ arr[i][1] = entry.getValue();
+ i++;
+ }
+
+ Slog.v(TAG, "converted " + i + " element(s)");
+ return arr;
+ }
+}
diff --git a/services/core/java/com/android/server/broadcastradio/Tuner.java b/services/core/java/com/android/server/broadcastradio/Tuner.java
index b9a1e81..06a5af5 100644
--- a/services/core/java/com/android/server/broadcastradio/Tuner.java
+++ b/services/core/java/com/android/server/broadcastradio/Tuner.java
@@ -28,6 +28,7 @@
import android.util.Slog;
import java.util.List;
+import java.util.Map;
class Tuner extends ITuner.Stub {
private static final String TAG = "BroadcastRadioService.Tuner";
@@ -86,7 +87,7 @@
private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
private native boolean nativeStartBackgroundScan(long nativeContext);
private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext,
- String filter);
+ Map<String, String> vendorFilter);
private native byte[] nativeGetImage(long nativeContext, int id);
@@ -242,10 +243,11 @@
}
@Override
- public List<RadioManager.ProgramInfo> getProgramList(String filter) {
+ public List<RadioManager.ProgramInfo> getProgramList(Map vendorFilter) {
+ Map<String, String> sFilter = vendorFilter;
synchronized (mLock) {
checkNotClosedLocked();
- List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter);
+ List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, sFilter);
if (list == null) {
throw new IllegalStateException("Program list is not ready");
}
diff --git a/services/core/java/com/android/server/broadcastradio/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/TunerCallback.java
index 25f3775..a87ae8d 100644
--- a/services/core/java/com/android/server/broadcastradio/TunerCallback.java
+++ b/services/core/java/com/android/server/broadcastradio/TunerCallback.java
@@ -86,8 +86,8 @@
}
@Override
- public void onProgramInfoChanged() {
- dispatch(() -> mClientCallback.onProgramInfoChanged());
+ public void onCurrentProgramInfoChanged(RadioManager.ProgramInfo info) {
+ dispatch(() -> mClientCallback.onCurrentProgramInfoChanged(info));
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 703e50a..0d935db 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -142,6 +142,18 @@
extraInfo = null;
}
+ // Clear any previous notification with lower priority, otherwise return. http://b/63676954.
+ // A new SIGN_IN notification with a new intent should override any existing one.
+ final int previousEventId = mNotificationTypeMap.get(id);
+ final NotificationType previousNotifyType = NotificationType.getFromId(previousEventId);
+ if (priority(previousNotifyType) > priority(notifyType)) {
+ Slog.d(TAG, String.format(
+ "ignoring notification %s for network %s with existing notification %s",
+ notifyType, id, previousNotifyType));
+ return;
+ }
+ clearNotification(id);
+
if (DBG) {
Slog.d(TAG, String.format(
"showNotification tag=%s event=%s transport=%s extraInfo=%s highPrioriy=%s",
@@ -274,4 +286,22 @@
NotificationType t = NotificationType.getFromId(eventId);
return (t != null) ? t.name() : "UNKNOWN";
}
+
+ private static int priority(NotificationType t) {
+ if (t == null) {
+ return 0;
+ }
+ switch (t) {
+ case SIGN_IN:
+ return 4;
+ case NO_INTERNET:
+ return 3;
+ case NETWORK_SWITCH:
+ return 2;
+ case LOST_INTERNET:
+ return 1;
+ default:
+ return 0;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index b0be8f7..015f7f0 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -832,20 +832,23 @@
// functions are ready to use.
//
// For more explanation, see b/62552150 .
- if (usbConnected && !usbConfigured) {
- // Nothing for us to do here.
- // TODO: consider ignoring DISCONNECTED broadcasts as well.
- return;
- }
-
synchronized (Tethering.this.mPublicSync) {
+ // Always record the state of RNDIS.
mRndisEnabled = rndisEnabled;
+
+ if (usbConnected && !usbConfigured) {
+ // Nothing to do here (only CONNECTED, not yet CONFIGURED).
+ return;
+ }
+
// start tethering if we have a request pending
if (usbConfigured && mRndisEnabled && mUsbTetherRequested) {
tetherMatchingInterfaces(
IControlsTethering.STATE_TETHERED,
ConnectivityManager.TETHERING_USB);
}
+
+ // TODO: Figure out how to remove the need for this variable.
mUsbTetherRequested = false;
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index fb911ce..fb8ae12 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -169,11 +169,17 @@
// a stylish color fade animation instead.
private boolean mColorFadeFadesConfig;
- // True if we need to transition to the off state when coming out of a doze state.
- // Some display hardware will show artifacts (flickers, etc) when transitioning from a doze
- // to a fully on state. In order to hide these, we first transition to off to let the system
- // animate the screen on as it normally would, which is a much smoother experience.
- private boolean mTransitionOffAfterDozeConfig;
+ // True if we need to fake a transition to off when coming out of a doze state.
+ // Some display hardware will blank itself when coming out of doze in order to hide
+ // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
+ // blank itself and begin an appropriate power on animation.
+ private boolean mDisplayBlanksAfterDozeConfig;
+
+ // True if there are only buckets of brightness values when the display is in the doze state,
+ // rather than a full range of values. If this is true, then we'll avoid animating the screen
+ // brightness since it'd likely be multiple jarring brightness transitions instead of just one
+ // to reach the final state.
+ private boolean mBrightnessBucketsInDozeConfig;
// The pending power request.
// Initially null until the first call to requestPowerState.
@@ -422,8 +428,11 @@
mColorFadeFadesConfig = resources.getBoolean(
com.android.internal.R.bool.config_animateScreenLights);
- mTransitionOffAfterDozeConfig = resources.getBoolean(
- com.android.internal.R.bool.config_displayTransitionOffAfterDoze);
+ mDisplayBlanksAfterDozeConfig = resources.getBoolean(
+ com.android.internal.R.bool.config_displayBlanksAfterDoze);
+
+ mBrightnessBucketsInDozeConfig = resources.getBoolean(
+ com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
@@ -788,7 +797,7 @@
boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
if ((state == Display.STATE_ON
&& mSkipRampState == RAMP_STATE_SKIP_NONE
- || state == Display.STATE_DOZE)
+ || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
&& !wasOrWillBeInVr) {
animateScreenBrightness(brightness,
slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
@@ -811,7 +820,7 @@
// Notify policy about screen turned on.
if (ready && state != Display.STATE_OFF
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
- mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
+ setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
mWindowManagerPolicy.screenTurnedOn();
}
@@ -894,10 +903,10 @@
}
private boolean setScreenState(int state) {
- return setScreenState(state, false /*force*/);
+ return setScreenState(state, false /*reportOnly*/);
}
- private boolean setScreenState(int state, boolean force) {
+ private boolean setScreenState(int state, boolean reportOnly) {
final boolean isOff = (state == Display.STATE_OFF);
if (mPowerState.getScreenState() != state) {
@@ -905,32 +914,24 @@
// actually turn the screen off.
if (isOff && !mScreenOffBecauseOfProximity) {
if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
- mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
+ setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
blockScreenOff();
mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
- if (force) {
- // If we're forcing the power state transition then immediately
- // unblock the screen off event. This keeps the lifecycle consistent,
- // so WindowManagerPolicy will always see screenTurningOff before
- // screenTurnedOff, but we don't actually block on them for the state
- // change.
- unblockScreenOff();
- } else {
- return false;
- }
+ unblockScreenOff();
} else if (mPendingScreenOffUnblocker != null) {
// Abort doing the state change until screen off is unblocked.
return false;
}
}
- mPowerState.setScreenState(state);
-
- // Tell battery stats about the transition.
- try {
- mBatteryStats.noteScreenState(state);
- } catch (RemoteException ex) {
- // same process
+ if (!reportOnly) {
+ mPowerState.setScreenState(state);
+ // Tell battery stats about the transition.
+ try {
+ mBatteryStats.noteScreenState(state);
+ } catch (RemoteException ex) {
+ // same process
+ }
}
}
@@ -942,7 +943,7 @@
// finished drawing underneath.
if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
&& !mScreenOffBecauseOfProximity) {
- mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+ setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
unblockScreenOn();
mWindowManagerPolicy.screenTurnedOff();
} else if (!isOff
@@ -952,10 +953,10 @@
// Complete the full state transition on -> turningOff -> off.
unblockScreenOff();
mWindowManagerPolicy.screenTurnedOff();
- mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+ setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
}
if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
- mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
+ setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
if (mPowerState.getColorFadeLevel() == 0.0f) {
blockScreenOn();
} else {
@@ -968,6 +969,11 @@
return mPendingScreenOnUnblocker == null;
}
+ private void setReportedScreenState(int state) {
+ Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
+ mReportedScreenStateToPolicy = state;
+ }
+
private int clampScreenBrightness(int value) {
return MathUtils.constrain(
value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
@@ -997,15 +1003,20 @@
mPendingScreenOff = false;
}
- if (mTransitionOffAfterDozeConfig &&
- Display.isDozeState(mPowerState.getScreenState())
+ if (mDisplayBlanksAfterDozeConfig
+ && Display.isDozeState(mPowerState.getScreenState())
&& !Display.isDozeState(target)) {
- setScreenState(Display.STATE_OFF, true /*force*/);
// Skip the screen off animation and add a black surface to hide the
- // contents of the screen. This will also trigger another power state update so that we
- // end up converging on the target state.
+ // contents of the screen.
+ mPowerState.prepareColorFade(mContext,
+ mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
mColorFadeOffAnimator.end();
- return;
+ // Some display hardware will blank itself on the transition between doze and non-doze
+ // but still on display states. In this case we want to report to policy that the
+ // display has turned off so it can prepare the appropriate power on animation, but we
+ // don't want to actually transition to the fully off state since that takes
+ // significantly longer to transition from.
+ setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
}
// If we were in the process of turning off the screen but didn't quite
@@ -1307,7 +1318,8 @@
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
pw.println(" mPendingScreenOff=" + mPendingScreenOff);
- pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
+ pw.println(" mReportedToPolicy=" +
+ reportedToPolicyToString(mReportedScreenStateToPolicy));
pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index d0c1580..763f56f 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
+import android.os.Trace;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Slog;
@@ -49,6 +50,7 @@
private static final String TAG = "DisplayPowerState";
private static boolean DEBUG = false;
+ private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
private final Handler mHandler;
private final Choreographer mChoreographer;
@@ -190,6 +192,7 @@
* Dismisses the color fade surface.
*/
public void dismissColorFade() {
+ Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
if (mColorFade != null) mColorFade.dismiss();
mColorFadePrepared = false;
mColorFadeReady = true;
@@ -328,6 +331,8 @@
if (mColorFadePrepared) {
mColorFade.draw(mColorFadeLevel);
+ Trace.traceCounter(Trace.TRACE_TAG_POWER,
+ COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100));
}
mColorFadeReady = true;
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index cdc973b..ce5f430 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -515,6 +515,7 @@
try {
final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);
+ Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -530,6 +531,8 @@
+ "id=" + displayId + ", brightness=" + brightness + ")");
try {
mBacklight.setBrightness(brightness);
+ Trace.traceCounter(Trace.TRACE_TAG_POWER,
+ "DisplayBrightness", brightness);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index b124a39..026921d 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -119,9 +119,9 @@
* </table>
*/
private static final float[] mColorTempCoefficients = new float[] {
- 0.0f, -0.0000000871377221f, -0.0000000753960646f,
- 0.0f, 0.000750142586f, .000725567598f,
- 1.0f, -.830130222f, -1.15546312f
+ 0.0f, -0.000000014365268757f, -0.000000000910931179f,
+ 0.0f, 0.000255092801250106f, 0.000207598323269139f,
+ 1.0f, -0.064156942434907716f, -0.349361641294833436f
};
private int mCurrentUser = UserHandle.USER_NULL;
diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
index 12827d0..b6bbd1b 100644
--- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java
@@ -95,7 +95,7 @@
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify enumerated:", e);
}
- return fingerId == 0; // done when id hits 0
+ return remaining == 0;
}
@Override
diff --git a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
index f4d2596..88d9ef4 100644
--- a/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
+++ b/services/core/java/com/android/server/fingerprint/InternalEnumerateClient.java
@@ -88,7 +88,7 @@
doFingerprintCleanup();
}
- return fingerId == 0; // done when id hits 0
+ return remaining == 0;
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a50ec49f..81bccdc 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -851,6 +851,7 @@
mSystemAudioActivated = on;
mService.announceSystemAudioModeChange(on);
}
+ startArcAction(on);
}
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index f885167..e25f3e6 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -76,6 +76,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.DeviceIdleController;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.job.JobStore.JobStatusFunctor;
import com.android.server.job.controllers.AppIdleController;
@@ -919,8 +920,57 @@
mControllers.add(AppIdleController.get(this));
mControllers.add(ContentObserverController.get(this));
mControllers.add(DeviceIdleJobsController.get(this));
+
+ // If the job store determined that it can't yet reschedule persisted jobs,
+ // we need to start watching the clock.
+ if (!mJobs.jobTimesInflatedValid()) {
+ Slog.w(TAG, "!!! RTC not yet good; tracking time updates for job scheduling");
+ context.registerReceiver(mTimeSetReceiver, new IntentFilter(Intent.ACTION_TIME_CHANGED));
+ }
}
+ private final BroadcastReceiver mTimeSetReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
+ // When we reach clock sanity, recalculate the temporal windows
+ // of all affected jobs.
+ if (mJobs.clockNowValidToInflate(System.currentTimeMillis())) {
+ Slog.i(TAG, "RTC now valid; recalculating persisted job windows");
+
+ // We've done our job now, so stop watching the time.
+ context.unregisterReceiver(this);
+
+ // And kick off the work to update the affected jobs, using a secondary
+ // thread instead of chugging away here on the main looper thread.
+ FgThread.getHandler().post(mJobTimeUpdater);
+ }
+ }
+ }
+ };
+
+ private final Runnable mJobTimeUpdater = () -> {
+ final ArrayList<JobStatus> toRemove = new ArrayList<>();
+ final ArrayList<JobStatus> toAdd = new ArrayList<>();
+ synchronized (mLock) {
+ // Note: we intentionally both look up the existing affected jobs and replace them
+ // with recalculated ones inside the same lock lifetime.
+ getJobStore().getRtcCorrectedJobsLocked(toAdd, toRemove);
+
+ // Now, at each position [i], we have both the existing JobStatus
+ // and the one that replaces it.
+ final int N = toAdd.size();
+ for (int i = 0; i < N; i++) {
+ final JobStatus oldJob = toRemove.get(i);
+ final JobStatus newJob = toAdd.get(i);
+ if (DEBUG) {
+ Slog.v(TAG, " replacing " + oldJob + " with " + newJob);
+ }
+ cancelJobImplLocked(oldJob, newJob, "deferred rtc calculation");
+ }
+ }
+ };
+
@Override
public void onStart() {
publishLocalService(JobSchedulerInternal.class, new LocalService());
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index a34e251..031bdd0 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -219,6 +219,10 @@
isDeadlineExpired, triggeredUris, triggeredAuthorities);
mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
+ // Once we'e begun executing a job, we by definition no longer care whether
+ // it was inflated from disk with not-yet-coherent delay/deadline bounds.
+ job.clearPersistedUtcTimes();
+
mVerb = VERB_BINDING;
scheduleOpTimeOutLocked();
final Intent intent = new Intent().setComponent(job.getServiceComponent());
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 84810be..62b06d6 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -72,10 +72,15 @@
/** Threshold to adjust how often we want to write to the db. */
private static final int MAX_OPS_BEFORE_WRITE = 1;
+
final Object mLock;
final JobSet mJobSet; // per-caller-uid tracking
final Context mContext;
+ // Bookkeeping around incorrect boot-time system clock
+ private final long mXmlTimestamp;
+ private boolean mRtcGood;
+
private int mDirtyOperations;
private static final Object sSingletonLock = new Object();
@@ -120,7 +125,52 @@
mJobSet = new JobSet();
- readJobMapFromDisk(mJobSet);
+ // If the current RTC is earlier than the timestamp on our persisted jobs file,
+ // we suspect that the RTC is uninitialized and so we cannot draw conclusions
+ // about persisted job scheduling.
+ //
+ // Note that if the persisted jobs file does not exist, we proceed with the
+ // assumption that the RTC is good. This is less work and is safe: if the
+ // clock updates to sanity then we'll be saving the persisted jobs file in that
+ // correct state, which is normal; or we'll wind up writing the jobs file with
+ // an incorrect historical timestamp. That's fine; at worst we'll reboot with
+ // a *correct* timestamp, see a bunch of overdue jobs, and run them; then
+ // settle into normal operation.
+ mXmlTimestamp = mJobsFile.getLastModifiedTime();
+ mRtcGood = (System.currentTimeMillis() > mXmlTimestamp);
+
+ readJobMapFromDisk(mJobSet, mRtcGood);
+ }
+
+ public boolean jobTimesInflatedValid() {
+ return mRtcGood;
+ }
+
+ public boolean clockNowValidToInflate(long now) {
+ return now >= mXmlTimestamp;
+ }
+
+ /**
+ * Find all the jobs that were affected by RTC clock uncertainty at boot time. Returns
+ * parallel lists of the existing JobStatus objects and of new, equivalent JobStatus instances
+ * with now-corrected time bounds.
+ */
+ public void getRtcCorrectedJobsLocked(final ArrayList<JobStatus> toAdd,
+ final ArrayList<JobStatus> toRemove) {
+ final long elapsedNow = SystemClock.elapsedRealtime();
+
+ // Find the jobs that need to be fixed up, collecting them for post-iteration
+ // replacement with their new versions
+ forEachJob(job -> {
+ final Pair<Long, Long> utcTimes = job.getPersistedUtcTimes();
+ if (utcTimes != null) {
+ Pair<Long, Long> elapsedRuntimes =
+ convertRtcBoundsToElapsed(utcTimes, elapsedNow);
+ toAdd.add(new JobStatus(job, elapsedRuntimes.first, elapsedRuntimes.second,
+ 0, job.getLastSuccessfulRunTime(), job.getLastFailedRunTime()));
+ toRemove.add(job);
+ }
+ });
}
/**
@@ -241,8 +291,6 @@
/**
* Every time the state changes we write all the jobs in one swath, instead of trying to
* track incremental changes.
- * @return Whether the operation was successful. This will only fail for e.g. if the system is
- * low on storage. If this happens, we continue as normal
*/
private void maybeWriteStatusToDiskAsync() {
mDirtyOperations++;
@@ -250,20 +298,21 @@
if (DEBUG) {
Slog.v(TAG, "Writing jobs to disk.");
}
- mIoHandler.post(new WriteJobsMapToDiskRunnable());
+ mIoHandler.removeCallbacks(mWriteRunnable);
+ mIoHandler.post(mWriteRunnable);
}
}
@VisibleForTesting
- public void readJobMapFromDisk(JobSet jobSet) {
- new ReadJobMapFromDiskRunnable(jobSet).run();
+ public void readJobMapFromDisk(JobSet jobSet, boolean rtcGood) {
+ new ReadJobMapFromDiskRunnable(jobSet, rtcGood).run();
}
/**
* Runnable that writes {@link #mJobSet} out to xml.
* NOTE: This Runnable locks on mLock
*/
- private final class WriteJobsMapToDiskRunnable implements Runnable {
+ private final Runnable mWriteRunnable = new Runnable() {
@Override
public void run() {
final long startElapsed = SystemClock.elapsedRealtime();
@@ -280,7 +329,7 @@
});
}
writeJobsMapImpl(storeCopy);
- if (JobSchedulerService.DEBUG) {
+ if (DEBUG) {
Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
- startElapsed) + "ms");
}
@@ -311,7 +360,7 @@
out.endTag(null, "job-info");
out.endDocument();
- // Write out to disk in one fell sweep.
+ // Write out to disk in one fell swoop.
FileOutputStream fos = mJobsFile.startWrite();
fos.write(baos.toByteArray());
mJobsFile.finishWrite(fos);
@@ -417,15 +466,27 @@
out.startTag(null, XML_TAG_ONEOFF);
}
+ // If we still have the persisted times, we need to record those directly because
+ // we haven't yet been able to calculate the usual elapsed-timebase bounds
+ // correctly due to wall-clock uncertainty.
+ Pair <Long, Long> utcJobTimes = jobStatus.getPersistedUtcTimes();
+ if (DEBUG && utcJobTimes != null) {
+ Slog.i(TAG, "storing original UTC timestamps for " + jobStatus);
+ }
+
+ final long nowRTC = System.currentTimeMillis();
+ final long nowElapsed = SystemClock.elapsedRealtime();
if (jobStatus.hasDeadlineConstraint()) {
// Wall clock deadline.
- final long deadlineWallclock = System.currentTimeMillis() +
- (jobStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
+ final long deadlineWallclock = (utcJobTimes == null)
+ ? nowRTC + (jobStatus.getLatestRunTimeElapsed() - nowElapsed)
+ : utcJobTimes.second;
out.attribute(null, "deadline", Long.toString(deadlineWallclock));
}
if (jobStatus.hasTimingDelayConstraint()) {
- final long delayWallclock = System.currentTimeMillis() +
- (jobStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
+ final long delayWallclock = (utcJobTimes == null)
+ ? nowRTC + (jobStatus.getEarliestRunTime() - nowElapsed)
+ : utcJobTimes.first;
out.attribute(null, "delay", Long.toString(delayWallclock));
}
@@ -443,6 +504,25 @@
out.endTag(null, XML_TAG_ONEOFF);
}
}
+ };
+
+ /**
+ * Translate the supplied RTC times to the elapsed timebase, with clamping appropriate
+ * to interpreting them as a job's delay + deadline times for alarm-setting purposes.
+ * @param rtcTimes a Pair<Long, Long> in which {@code first} is the "delay" earliest
+ * allowable runtime for the job, and {@code second} is the "deadline" time at which
+ * the job becomes overdue.
+ */
+ private static Pair<Long, Long> convertRtcBoundsToElapsed(Pair<Long, Long> rtcTimes,
+ long nowElapsed) {
+ final long nowWallclock = System.currentTimeMillis();
+ final long earliest = (rtcTimes.first > JobStatus.NO_EARLIEST_RUNTIME)
+ ? nowElapsed + Math.max(rtcTimes.first - nowWallclock, 0)
+ : JobStatus.NO_EARLIEST_RUNTIME;
+ final long latest = (rtcTimes.second < JobStatus.NO_LATEST_RUNTIME)
+ ? nowElapsed + Math.max(rtcTimes.second - nowWallclock, 0)
+ : JobStatus.NO_LATEST_RUNTIME;
+ return Pair.create(earliest, latest);
}
/**
@@ -451,13 +531,15 @@
*/
private final class ReadJobMapFromDiskRunnable implements Runnable {
private final JobSet jobSet;
+ private final boolean rtcGood;
/**
* @param jobSet Reference to the (empty) set of JobStatus objects that back the JobStore,
* so that after disk read we can populate it directly.
*/
- ReadJobMapFromDiskRunnable(JobSet jobSet) {
+ ReadJobMapFromDiskRunnable(JobSet jobSet, boolean rtcIsGood) {
this.jobSet = jobSet;
+ this.rtcGood = rtcIsGood;
}
@Override
@@ -466,7 +548,7 @@
List<JobStatus> jobs;
FileInputStream fis = mJobsFile.openRead();
synchronized (mLock) {
- jobs = readJobMapImpl(fis);
+ jobs = readJobMapImpl(fis, rtcGood);
if (jobs != null) {
long now = SystemClock.elapsedRealtime();
IActivityManager am = ActivityManager.getService();
@@ -480,21 +562,21 @@
}
fis.close();
} catch (FileNotFoundException e) {
- if (JobSchedulerService.DEBUG) {
+ if (DEBUG) {
Slog.d(TAG, "Could not find jobs file, probably there was nothing to load.");
}
} catch (XmlPullParserException e) {
- if (JobSchedulerService.DEBUG) {
+ if (DEBUG) {
Slog.d(TAG, "Error parsing xml.", e);
}
} catch (IOException e) {
- if (JobSchedulerService.DEBUG) {
+ if (DEBUG) {
Slog.d(TAG, "Error parsing xml.", e);
}
}
}
- private List<JobStatus> readJobMapImpl(FileInputStream fis)
+ private List<JobStatus> readJobMapImpl(FileInputStream fis, boolean rtcIsGood)
throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, StandardCharsets.UTF_8.name());
@@ -533,7 +615,7 @@
tagName = parser.getName();
// Start reading job.
if ("job".equals(tagName)) {
- JobStatus persistedJob = restoreJobFromXml(parser);
+ JobStatus persistedJob = restoreJobFromXml(rtcIsGood, parser);
if (persistedJob != null) {
if (DEBUG) {
Slog.d(TAG, "Read out " + persistedJob);
@@ -556,8 +638,8 @@
* will take the parser into the body of the job tag.
* @return Newly instantiated job holding all the information we just read out of the xml tag.
*/
- private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException,
- IOException {
+ private JobStatus restoreJobFromXml(boolean rtcIsGood, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
JobInfo.Builder jobBuilder;
int uid, sourceUserId;
long lastSuccessfulRunTime;
@@ -621,10 +703,10 @@
return null;
}
- // Tuple of (earliest runtime, latest runtime) in elapsed realtime after disk load.
- Pair<Long, Long> elapsedRuntimes;
+ // Tuple of (earliest runtime, latest runtime) in UTC.
+ final Pair<Long, Long> rtcRuntimes;
try {
- elapsedRuntimes = buildExecutionTimesFromXml(parser);
+ rtcRuntimes = buildRtcExecutionTimesFromXml(parser);
} catch (NumberFormatException e) {
if (DEBUG) {
Slog.d(TAG, "Error parsing execution time parameters, skipping.");
@@ -633,6 +715,8 @@
}
final long elapsedNow = SystemClock.elapsedRealtime();
+ Pair<Long, Long> elapsedRuntimes = convertRtcBoundsToElapsed(rtcRuntimes, elapsedNow);
+
if (XML_TAG_PERIODIC.equals(parser.getName())) {
try {
String val = parser.getAttributeValue(null, "period");
@@ -722,7 +806,8 @@
JobStatus js = new JobStatus(
jobBuilder.build(), uid, sourcePackageName, sourceUserId, sourceTag,
elapsedRuntimes.first, elapsedRuntimes.second,
- lastSuccessfulRunTime, lastFailedRunTime);
+ lastSuccessfulRunTime, lastFailedRunTime,
+ (rtcIsGood) ? null : rtcRuntimes);
return js;
}
@@ -778,6 +863,32 @@
}
/**
+ * Extract a job's earliest/latest run time data from XML. These are returned in
+ * unadjusted UTC wall clock time, because we do not yet know whether the system
+ * clock is reliable for purposes of calculating deltas from 'now'.
+ *
+ * @param parser
+ * @return A Pair of timestamps in UTC wall-clock time. The first is the earliest
+ * time at which the job is to become runnable, and the second is the deadline at
+ * which it becomes overdue to execute.
+ * @throws NumberFormatException
+ */
+ private Pair<Long, Long> buildRtcExecutionTimesFromXml(XmlPullParser parser)
+ throws NumberFormatException {
+ String val;
+ // Pull out execution time data.
+ val = parser.getAttributeValue(null, "delay");
+ final long earliestRunTimeRtc = (val != null)
+ ? Long.parseLong(val)
+ : JobStatus.NO_EARLIEST_RUNTIME;
+ val = parser.getAttributeValue(null, "deadline");
+ final long latestRunTimeRtc = (val != null)
+ ? Long.parseLong(val)
+ : JobStatus.NO_LATEST_RUNTIME;
+ return Pair.create(earliestRunTimeRtc, latestRunTimeRtc);
+ }
+
+ /**
* Convenience function to read out and convert deadline and delay from xml into elapsed real
* time.
* @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 9658da7..303b000 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -28,10 +28,12 @@
import android.os.UserHandle;
import android.text.format.Time;
import android.util.ArraySet;
+import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;
import com.android.server.job.GrantedUriPermissions;
+import com.android.server.job.JobSchedulerService;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -50,6 +52,7 @@
*/
public final class JobStatus {
static final String TAG = "JobSchedulerService";
+ static final boolean DEBUG = JobSchedulerService.DEBUG;
public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
public static final long NO_EARLIEST_RUNTIME = 0L;
@@ -196,6 +199,18 @@
private long mLastFailedRunTime;
/**
+ * Transient: when a job is inflated from disk before we have a reliable RTC clock time,
+ * we retain the canonical (delay, deadline) scheduling tuple read out of the persistent
+ * store in UTC so that we can fix up the job's scheduling criteria once we get a good
+ * wall-clock time. If we have to persist the job again before the clock has been updated,
+ * we record these times again rather than calculating based on the earliest/latest elapsed
+ * time base figures.
+ *
+ * 'first' is the earliest/delay time, and 'second' is the latest/deadline time.
+ */
+ private Pair<Long, Long> mPersistedUtcTimes;
+
+ /**
* For use only by ContentObserverController: state it is maintaining about content URIs
* being observed.
*/
@@ -280,13 +295,20 @@
mLastFailedRunTime = lastFailedRunTime;
}
- /** Copy constructor. */
+ /** Copy constructor: used specifically when cloning JobStatus objects for persistence,
+ * so we preserve RTC window bounds if the source object has them. */
public JobStatus(JobStatus jobStatus) {
this(jobStatus.getJob(), jobStatus.getUid(),
jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
jobStatus.getSourceTag(), jobStatus.getNumFailures(),
jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(),
jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime());
+ mPersistedUtcTimes = jobStatus.mPersistedUtcTimes;
+ if (jobStatus.mPersistedUtcTimes != null) {
+ if (DEBUG) {
+ Slog.i(TAG, "Cloning job with persisted run times", new RuntimeException("here"));
+ }
+ }
}
/**
@@ -298,10 +320,22 @@
*/
public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
- long lastSuccessfulRunTime, long lastFailedRunTime) {
+ long lastSuccessfulRunTime, long lastFailedRunTime,
+ Pair<Long, Long> persistedExecutionTimesUTC) {
this(job, callingUid, sourcePackageName, sourceUserId, sourceTag, 0,
earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
lastSuccessfulRunTime, lastFailedRunTime);
+
+ // Only during initial inflation do we record the UTC-timebase execution bounds
+ // read from the persistent store. If we ever have to recreate the JobStatus on
+ // the fly, it means we're rescheduling the job; and this means that the calculated
+ // elapsed timebase bounds intrinsically become correct.
+ this.mPersistedUtcTimes = persistedExecutionTimesUTC;
+ if (persistedExecutionTimesUTC != null) {
+ if (DEBUG) {
+ Slog.i(TAG, "+ restored job with RTC times because of bad boot clock");
+ }
+ }
}
/** Create a new job to be rescheduled with the provided parameters. */
@@ -612,6 +646,14 @@
return latestRunTimeElapsedMillis;
}
+ public Pair<Long, Long> getPersistedUtcTimes() {
+ return mPersistedUtcTimes;
+ }
+
+ public void clearPersistedUtcTimes() {
+ mPersistedUtcTimes = null;
+ }
+
boolean setChargingConstraintSatisfied(boolean state) {
return setConstraintSatisfied(CONSTRAINT_CHARGING, state);
}
@@ -799,6 +841,9 @@
if (job.isRequireDeviceIdle()) {
sb.append(" IDLE");
}
+ if (job.isPeriodic()) {
+ sb.append(" PERIODIC");
+ }
if (job.isPersisted()) {
sb.append(" PERSISTED");
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index cdf25cf..436ea3c 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -543,7 +543,9 @@
loadPropertiesFromResource(context, mProperties);
String lpp_profile = mProperties.getProperty("LPP_PROFILE");
// set the persist property LPP_PROFILE for the value
- SystemProperties.set(LPP_PROFILE, lpp_profile);
+ if (lpp_profile != null) {
+ SystemProperties.set(LPP_PROFILE, lpp_profile);
+ }
} else {
// reset the persist property
SystemProperties.set(LPP_PROFILE, "");
@@ -1052,8 +1054,15 @@
// download tasks overrun.
synchronized (mLock) {
if (mDownloadXtraWakeLock.isHeld()) {
- mDownloadXtraWakeLock.release();
- if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
+ // This wakelock may have time-out, if a timeout was specified.
+ // Catch (and ignore) any timeout exceptions.
+ try {
+ mDownloadXtraWakeLock.release();
+ if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
+ } catch (Exception e) {
+ Log.i(TAG, "Wakelock timeout & release race exception in "
+ + "handleDownloadXtraData()", e);
+ }
} else {
Log.e(TAG, "WakeLock expired before release in "
+ "handleDownloadXtraData()");
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 62332c9..c012ee4 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -41,6 +41,7 @@
private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB.
private static final String DEFAULT_USER_AGENT = "Android";
private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
+ private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(60);
private final String[] mXtraServers;
// to load balance our server requests
@@ -123,6 +124,7 @@
"x-wap-profile",
"http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
connection.setConnectTimeout(CONNECTION_TIMEOUT_MS);
+ connection.setReadTimeout(READ_TIMEOUT_MS);
connection.connect();
int statusCode = connection.getResponseCode();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a105c84..2f166e9 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1223,6 +1223,7 @@
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(30)
+ .setCriticalToDeviceEncryption(true)
.build());
// Key imported, obtain a reference to it.
SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index 3c236b4..d39679d 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -160,6 +160,11 @@
final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
if (havePassword || havePattern) {
+ if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(mCurrentUserId)) {
+ getOutPrintWriter().println("Profile uses unified challenge");
+ return false;
+ }
+
try {
final boolean result;
if (havePassword) {
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 603e46a..0e4b08f 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -625,8 +625,8 @@
PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
byte[] pwdToken = computePasswordToken(userCredential, pwd);
- GateKeeperResponse response = gatekeeper.verify(fakeUid(persistentData.userId),
- pwd.passwordHandle, passwordTokenToGkInput(pwdToken));
+ GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(persistentData.userId),
+ 0 /* challenge */, pwd.passwordHandle, passwordTokenToGkInput(pwdToken));
return VerifyCredentialResponse.fromGateKeeperResponse(response);
} else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) {
PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f70486a..aabb245 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
+import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
@@ -311,6 +312,7 @@
private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
private static final String ATTR_USAGE_BYTES = "usageBytes";
private static final String ATTR_USAGE_TIME = "usageTime";
+ private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
private static final String ACTION_ALLOW_BACKGROUND =
"com.android.server.net.action.ALLOW_BACKGROUND";
@@ -372,8 +374,10 @@
/** Currently active network rules for ifaces. */
final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
- /** Defined subscription plans. */
+ /** Map from subId to subscription plans. */
final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
+ /** Map from subId to package name that owns subscription plans. */
+ final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
/** Defined UID policies. */
@GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
@@ -1261,13 +1265,8 @@
* @param subId that has its associated NetworkPolicy updated if necessary
* @return if any policies were updated
*/
- private boolean maybeUpdateMobilePolicyCycleNL(int subId) {
- if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleNL()");
- final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
-
- if (config == null) {
- return false;
- }
+ private boolean maybeUpdateMobilePolicyCycleAL(int subId) {
+ if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
boolean policyUpdated = false;
final String subscriberId = TelephonyManager.from(mContext).getSubscriberId(subId);
@@ -1278,48 +1277,10 @@
for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
final NetworkTemplate template = mNetworkPolicy.keyAt(i);
if (template.matches(probeIdent)) {
- NetworkPolicy policy = mNetworkPolicy.valueAt(i);
-
- // only update the policy if the user didn't change any of the defaults.
- if (!policy.inferred) {
- // TODO: inferred could be split, so that if a user changes their data limit or
- // warning, it doesn't prevent their cycle date from being updated.
- if (LOGD) Slog.v(TAG, "Didn't update NetworkPolicy because policy.inferred");
- continue;
- }
-
- final int currentCycleDay;
- if (policy.cycleRule.isMonthly()) {
- currentCycleDay = policy.cycleRule.start.getDayOfMonth();
- } else {
- currentCycleDay = NetworkPolicy.CYCLE_NONE;
- }
-
- final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
- final long warningBytes = getWarningBytesFromCarrierConfig(config,
- policy.warningBytes);
- final long limitBytes = getLimitBytesFromCarrierConfig(config,
- policy.limitBytes);
-
- if (currentCycleDay == cycleDay &&
- policy.warningBytes == warningBytes &&
- policy.limitBytes == limitBytes) {
- continue;
- }
-
- policyUpdated = true;
- policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
- policy.warningBytes = warningBytes;
- policy.limitBytes = limitBytes;
-
- if (LOGD) {
- Slog.d(TAG, "Updated NetworkPolicy " + policy + " which matches subscriber "
- + NetworkIdentity.scrubSubscriberId(subscriberId)
- + " from CarrierConfigManager");
- }
+ final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
+ policyUpdated |= updateDefaultMobilePolicyAL(subId, policy);
}
}
-
return policyUpdated;
}
@@ -1441,7 +1402,7 @@
synchronized (mNetworkPoliciesSecondLock) {
final boolean added = ensureActiveMobilePolicyAL(subId, subscriberId);
if (added) return;
- final boolean updated = maybeUpdateMobilePolicyCycleNL(subId);
+ final boolean updated = maybeUpdateMobilePolicyCycleAL(subId);
if (!updated) return;
// update network and notification rules, as the data cycle changed and it's
// possible that we should be triggering warnings/limits now
@@ -1598,12 +1559,6 @@
final NetworkPolicy policy = mNetworkRules.keyAt(i);
final String[] ifaces = mNetworkRules.valueAt(i);
- final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
- .cycleIterator(policy).next();
- final long start = cycle.first.toInstant().toEpochMilli();
- final long end = cycle.second.toInstant().toEpochMilli();
- final long totalBytes = getTotalBytes(policy.template, start, end);
-
if (LOGD) {
Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces));
}
@@ -1612,19 +1567,27 @@
final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
if (hasLimit || policy.metered) {
final long quotaBytes;
- if (!hasLimit) {
+ if (hasLimit && policy.hasCycle()) {
+ final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
+ .cycleIterator(policy).next();
+ final long start = cycle.first.toInstant().toEpochMilli();
+ final long end = cycle.second.toInstant().toEpochMilli();
+ final long totalBytes = getTotalBytes(policy.template, start, end);
+
+ if (policy.lastLimitSnooze >= start) {
+ // snoozing past quota, but we still need to restrict apps,
+ // so push really high quota.
+ quotaBytes = Long.MAX_VALUE;
+ } else {
+ // remaining "quota" bytes are based on total usage in
+ // current cycle. kernel doesn't like 0-byte rules, so we
+ // set 1-byte quota and disable the radio later.
+ quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
+ }
+ } else {
// metered network, but no policy limit; we still need to
// restrict apps, so push really high quota.
quotaBytes = Long.MAX_VALUE;
- } else if (policy.lastLimitSnooze >= start) {
- // snoozing past quota, but we still need to restrict apps,
- // so push really high quota.
- quotaBytes = Long.MAX_VALUE;
- } else {
- // remaining "quota" bytes are based on total usage in
- // current cycle. kernel doesn't like 0-byte rules, so we
- // set 1-byte quota and disable the radio later.
- quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
}
if (ifaces.length > 1) {
@@ -1739,28 +1702,89 @@
@VisibleForTesting
public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
- PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
-
- final int cycleDay = getCycleDayFromCarrierConfig(config,
- ZonedDateTime.now().getDayOfMonth());
- final long warningBytes = getWarningBytesFromCarrierConfig(config,
- getPlatformDefaultWarningBytes());
- final long limitBytes = getLimitBytesFromCarrierConfig(config,
- getPlatformDefaultLimitBytes());
-
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
- final RecurrenceRule cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
+ final RecurrenceRule cycleRule = NetworkPolicy
+ .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
- warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
+ getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(),
+ SNOOZE_NEVER, SNOOZE_NEVER, true, true);
+ synchronized (mUidRulesFirstLock) {
+ synchronized (mNetworkPoliciesSecondLock) {
+ updateDefaultMobilePolicyAL(subId, policy);
+ }
+ }
return policy;
}
+ /**
+ * Update the given {@link NetworkPolicy} based on any carrier-provided
+ * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}.
+ * Leaves policy untouched if the user has modified it.
+ *
+ * @return if the policy was modified
+ */
+ private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
+ if (!policy.inferred) {
+ if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
+ return false;
+ }
+
+ final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
+ policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
+ policy.lastLimitSnooze, policy.metered, policy.inferred);
+
+ final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
+ if (!ArrayUtils.isEmpty(plans)) {
+ final SubscriptionPlan plan = plans[0];
+ policy.cycleRule = plan.getCycleRule();
+ final long planLimitBytes = plan.getDataLimitBytes();
+ if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
+ policy.warningBytes = getPlatformDefaultWarningBytes();
+ policy.limitBytes = getPlatformDefaultLimitBytes();
+ } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
+ policy.warningBytes = NetworkPolicy.WARNING_DISABLED;
+ policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
+ } else {
+ policy.warningBytes = (planLimitBytes * 9) / 10;
+ switch (plan.getDataLimitBehavior()) {
+ case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED:
+ case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED:
+ policy.limitBytes = planLimitBytes;
+ break;
+ default:
+ policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
+ break;
+ }
+ }
+ } else {
+ final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+ final int currentCycleDay;
+ if (policy.cycleRule.isMonthly()) {
+ currentCycleDay = policy.cycleRule.start.getDayOfMonth();
+ } else {
+ currentCycleDay = NetworkPolicy.CYCLE_NONE;
+ }
+ final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
+ policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
+ policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes);
+ policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes);
+ }
+
+ if (policy.equals(original)) {
+ return false;
+ } else {
+ Slog.d(TAG, "Updated " + original + " to " + policy);
+ return true;
+ }
+ }
+
private void readPolicyAL() {
if (LOGV) Slog.v(TAG, "readPolicyAL()");
// clear any existing policy and read from disk
mNetworkPolicy.clear();
mSubscriptionPlans.clear();
+ mSubscriptionPlansOwner.clear();
mUidPolicy.clear();
FileInputStream fis = null;
@@ -1902,6 +1926,9 @@
mSubscriptionPlans.put(subId, ArrayUtils.appendElement(
SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
+ final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
+ mSubscriptionPlansOwner.put(subId, ownerPackage);
+
} else if (TAG_UID_POLICY.equals(tag)) {
final int uid = readIntAttribute(in, ATTR_UID);
final int policy = readIntAttribute(in, ATTR_POLICY);
@@ -2074,12 +2101,14 @@
// write all known subscription plans
for (int i = 0; i < mSubscriptionPlans.size(); i++) {
final int subId = mSubscriptionPlans.keyAt(i);
+ final String ownerPackage = mSubscriptionPlansOwner.get(subId);
final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
if (ArrayUtils.isEmpty(plans)) continue;
for (SubscriptionPlan plan : plans) {
out.startTag(null, TAG_SUBSCRIPTION_PLAN);
writeIntAttribute(out, ATTR_SUB_ID, subId);
+ writeStringAttribute(out, ATTR_OWNER_PACKAGE, ownerPackage);
final RecurrenceRule cycleRule = plan.getCycleRule();
writeStringAttribute(out, ATTR_CYCLE_START,
RecurrenceRule.convertZonedDateTime(cycleRule.start));
@@ -2589,14 +2618,6 @@
// Verify they're not lying about package name
mAppOps.checkPackage(callingUid, callingPackage);
- // Verify they have phone permission from user
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
- if (mAppOps.checkOp(AppOpsManager.OP_READ_PHONE_STATE, callingUid,
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
- throw new SecurityException(
- "Calling package " + callingPackage + " does not hold " + READ_PHONE_STATE);
- }
-
final SubscriptionInfo si;
final PersistableBundle config;
final long token = Binder.clearCallingIdentity();
@@ -2609,8 +2630,10 @@
}
// First check: is caller the CarrierService?
- if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
- return;
+ if (si != null) {
+ if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
+ return;
+ }
}
// Second check: has the CarrierService delegated access?
@@ -2630,8 +2653,8 @@
return;
}
- throw new SecurityException("Calling package " + callingPackage
- + " has no access to subscription plans for " + subId);
+ // Final check: does the caller hold a permission?
+ mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
}
@Override
@@ -2650,6 +2673,22 @@
.setDataUsage(1 * TrafficStats.GB_IN_BYTES,
ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
.build());
+ plans.add(SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
+ .setTitle("G-Mobile Happy")
+ .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
+ SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
+ .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
+ .build());
+ plans.add(SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
+ .setTitle("G-Mobile, Charged after limit")
+ .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
+ .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
+ .build());
} else if ("month_soft".equals(fake)) {
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
@@ -2661,6 +2700,23 @@
.setDataUsage(1 * TrafficStats.GB_IN_BYTES,
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
+ plans.add(SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
+ .setTitle("G-Mobile, Throttled after limit")
+ .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
+ .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
+ .build());
+ plans.add(SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
+ .setTitle("G-Mobile, No data connection after limit")
+ .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
+ .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
+ .build());
+
} else if ("month_none".equals(fake)) {
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
@@ -2691,6 +2747,8 @@
ZonedDateTime.now().plusDays(20))
.setTitle("G-Mobile Nickel Nights")
.setSummary("5¢/GB between 1-5AM")
+ .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
.setDataUsage(15 * TrafficStats.MB_IN_BYTES,
ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
.build());
@@ -2699,18 +2757,39 @@
ZonedDateTime.now().plusDays(20))
.setTitle("G-Mobile Bonus 3G")
.setSummary("Unlimited 3G data")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
.setDataUsage(300 * TrafficStats.MB_IN_BYTES,
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
+ } else if ("unlimited".equals(fake)) {
+ plans.add(SubscriptionPlan.Builder
+ .createNonrecurring(ZonedDateTime.now().minusDays(20),
+ ZonedDateTime.now().plusDays(10))
+ .setTitle("G-Mobile Awesome")
+ .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
+ SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
+ .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
+ ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
+ .build());
}
return plans.toArray(new SubscriptionPlan[plans.size()]);
}
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
- return mSubscriptionPlans.get(subId);
+ // Only give out plan details to the package that defined them,
+ // so that we don't risk leaking plans between apps. We always
+ // let in core system components (like the Settings app).
+ final String ownerPackage = mSubscriptionPlansOwner.get(subId);
+ if (Objects.equals(ownerPackage, callingPackage)
+ || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)) {
+ return mSubscriptionPlans.get(subId);
+ } else {
+ Log.w(TAG, "Not returning plans because caller " + callingPackage
+ + " doesn't match owner " + ownerPackage);
+ return null;
+ }
}
}
}
@@ -2729,8 +2808,13 @@
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
mSubscriptionPlans.put(subId, plans);
- // TODO: update any implicit details from newly defined plans
- handleNetworkPoliciesUpdateAL(false);
+ mSubscriptionPlansOwner.put(subId, callingPackage);
+
+ final String subscriberId = mContext.getSystemService(TelephonyManager.class)
+ .getSubscriberId(subId);
+ ensureActiveMobilePolicyAL(subId, subscriberId);
+ maybeUpdateMobilePolicyCycleAL(subId);
+ handleNetworkPoliciesUpdateAL(true);
}
}
} finally {
@@ -2766,6 +2850,9 @@
fout.print("Restrict background: "); fout.println(mRestrictBackground);
fout.print("Restrict power: "); fout.println(mRestrictPower);
fout.print("Device idle: "); fout.println(mDeviceIdleMode);
+ fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
+
+ fout.println();
fout.println("Network policies:");
fout.increaseIndent();
for (int i = 0; i < mNetworkPolicy.size(); i++) {
@@ -2773,8 +2860,24 @@
}
fout.decreaseIndent();
- fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
+ fout.println();
+ fout.println("Subscription plans:");
+ fout.increaseIndent();
+ for (int i = 0; i < mSubscriptionPlans.size(); i++) {
+ final int subId = mSubscriptionPlans.keyAt(i);
+ fout.println("Subscriber ID " + subId + ":");
+ fout.increaseIndent();
+ final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
+ if (!ArrayUtils.isEmpty(plans)) {
+ for (SubscriptionPlan plan : plans) {
+ fout.println(plan);
+ }
+ }
+ fout.decreaseIndent();
+ }
+ fout.decreaseIndent();
+ fout.println();
fout.println("Policy for UIDs:");
fout.increaseIndent();
int size = mUidPolicy.size();
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
index c1a7ac6..c165fc1 100644
--- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -52,6 +52,7 @@
private boolean mConnected;
private long mTime;
+ private boolean mIsAlarm;
public CountdownConditionProvider() {
if (DEBUG) Slog.d(TAG, "new CountdownConditionProvider()");
@@ -110,9 +111,11 @@
public void onSubscribe(Uri conditionId) {
if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
mTime = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+ mIsAlarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId);
final AlarmManager alarms = (AlarmManager)
mContext.getSystemService(Context.ALARM_SERVICE);
- final Intent intent = new Intent(ACTION).putExtra(EXTRA_CONDITION_ID, conditionId)
+ final Intent intent = new Intent(ACTION)
+ .putExtra(EXTRA_CONDITION_ID, conditionId)
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -123,7 +126,7 @@
DateUtils.getRelativeTimeSpanString(mTime, now, DateUtils.MINUTE_IN_MILLIS);
if (mTime <= now) {
// in the past, already false
- notifyCondition(newCondition(mTime, Condition.STATE_FALSE));
+ notifyCondition(newCondition(mTime, mIsAlarm, Condition.STATE_FALSE));
} else {
// in the future, set an alarm
alarms.setExact(AlarmManager.RTC_WAKEUP, mTime, pendingIntent);
@@ -145,17 +148,18 @@
public void onReceive(Context context, Intent intent) {
if (ACTION.equals(intent.getAction())) {
final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID);
+ final boolean alarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId);
final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId);
if (time > 0) {
- notifyCondition(newCondition(time, Condition.STATE_FALSE));
+ notifyCondition(newCondition(time, alarm, Condition.STATE_FALSE));
}
}
}
}
- private static final Condition newCondition(long time, int state) {
- return new Condition(ZenModeConfig.toCountdownConditionId(time),
+ private static final Condition newCondition(long time, boolean alarm, int state) {
+ return new Condition(ZenModeConfig.toCountdownConditionId(time, alarm),
"", "", "", 0, state,Condition.FLAG_RELEVANT_NOW);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index fb391f8..abf391e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -21,6 +21,7 @@
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.UserHandle.USER_NULL;
import static android.service.notification.NotificationListenerService
.NOTIFICATION_CHANNEL_OR_GROUP_ADDED;
import static android.service.notification.NotificationListenerService
@@ -134,6 +135,7 @@
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeProto;
+import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -405,8 +407,7 @@
}
- protected void readDefaultApprovedServices() {
- final int userId = UserHandle.USER_SYSTEM;
+ protected void readDefaultApprovedServices(int userId) {
String defaultListenerAccess = getContext().getResources().getString(
com.android.internal.R.string.config_defaultListenerAccessPackages);
if (defaultListenerAccess != null) {
@@ -488,7 +489,7 @@
} catch (FileNotFoundException e) {
// No data yet
// Load default managed services approvals
- readDefaultApprovedServices();
+ readDefaultApprovedServices(UserHandle.USER_SYSTEM);
} catch (IOException e) {
Log.wtf(TAG, "Unable to read notification policy", e);
} catch (NumberFormatException e) {
@@ -977,7 +978,7 @@
// turn off LED when user passes through lock screen
mNotificationLight.turnOff();
} else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
- final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
// reload per-user settings
mSettingsObserver.update(null);
mUserProfiles.updateCache(context);
@@ -987,14 +988,18 @@
mAssistants.onUserSwitched(user);
mZenModeHelper.onUserSwitched(user);
} else if (action.equals(Intent.ACTION_USER_ADDED)) {
- mUserProfiles.updateCache(context);
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
+ if (userId != USER_NULL) {
+ mUserProfiles.updateCache(context);
+ readDefaultApprovedServices(userId);
+ }
} else if (action.equals(Intent.ACTION_USER_REMOVED)) {
- final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
mZenModeHelper.onUserRemoved(user);
mRankingHelper.onUserRemoved(user);
savePolicyFile();
} else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
- final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
mConditionProviders.onUserUnlocked(user);
mListeners.onUserUnlocked(user);
mAssistants.onUserUnlocked(user);
@@ -3039,7 +3044,7 @@
final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg));
if (removed != null) {
boolean wasPosted = removeFromNotificationListsLocked(removed);
- cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED, wasPosted);
+ cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED, wasPosted, null);
}
}
}
@@ -3502,8 +3507,11 @@
private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag,
NotificationRecord r) {
final String pkg = r.sbn.getPackageName();
+ final String dialerPackage =
+ getContext().getSystemService(TelecomManager.class).getSystemDialerPackage();
final boolean isSystemNotification =
- isUidSystemOrPhone(callingUid) || ("android".equals(pkg));
+ isUidSystemOrPhone(callingUid) || ("android".equals(pkg))
+ || TextUtils.equals(pkg, dialerPackage);
final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
// Limit the number of notifications that any given package except the android
@@ -3678,7 +3686,7 @@
.addTaggedData(MetricsEvent.NOTIFICATION_SNOOZED_CRITERIA,
mSnoozeCriterionId == null ? 0 : 1));
boolean wasPosted = removeFromNotificationListsLocked(r);
- cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted);
+ cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null);
updateLightsLocked();
if (mSnoozeCriterionId != null) {
mAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
@@ -4509,7 +4517,7 @@
@GuardedBy("mNotificationLock")
private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason,
- boolean wasPosted) {
+ boolean wasPosted, String listenerName) {
final String canceledKey = r.getKey();
// Record caller.
@@ -4609,7 +4617,7 @@
.setType(MetricsEvent.TYPE_DISMISS)
.setSubtype(reason));
EventLogTags.writeNotificationCanceled(canceledKey, reason,
- r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now));
+ r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now), listenerName);
}
/**
@@ -4652,7 +4660,7 @@
// Cancel the notification.
boolean wasPosted = removeFromNotificationListsLocked(r);
- cancelNotificationLocked(r, sendDelete, reason, wasPosted);
+ cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName);
cancelGroupChildrenLocked(r, callingUid, callingPid, listenerName,
sendDelete, null);
updateLightsLocked();
@@ -4778,7 +4786,7 @@
notificationList.remove(i);
mNotificationsByKey.remove(r.getKey());
canceledNotifications.add(r);
- cancelNotificationLocked(r, sendDelete, reason, wasPosted);
+ cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName);
}
if (canceledNotifications != null) {
final int M = canceledNotifications.size();
@@ -4888,7 +4896,7 @@
childSbn.getTag(), userId, 0, 0, reason, listenerName);
notificationList.remove(i);
mNotificationsByKey.remove(childR.getKey());
- cancelNotificationLocked(childR, sendDelete, reason, wasPosted);
+ cancelNotificationLocked(childR, sendDelete, reason, wasPosted, listenerName);
}
}
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 7667ff4..9622a24 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -553,6 +553,13 @@
existing.setDescription(channel.getDescription());
existing.setBlockableSystem(channel.isBlockableSystem());
+ // Apps are allowed to downgrade channel importance if the user has not changed any
+ // fields on this channel yet.
+ if (existing.getUserLockedFields() == 0 &&
+ channel.getImportance() < existing.getImportance()) {
+ existing.setImportance(channel.getImportance());
+ }
+
updateConfig();
return;
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index d1aecb1..b217677 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
@@ -701,6 +702,16 @@
LOCATION_PERMISSIONS, true, userId);
}
+ // Ringtone Picker
+ Intent ringtonePickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+ PackageParser.Package ringtonePickerPackage =
+ getDefaultSystemHandlerActivityPackageLPr(ringtonePickerIntent, userId);
+ if (ringtonePickerPackage != null
+ && doesPackageSupportRuntimePermissions(ringtonePickerPackage)) {
+ grantRuntimePermissionsLPw(ringtonePickerPackage,
+ STORAGE_PERMISSIONS, true, userId);
+ }
+
mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 4600c32..b5ddf8c 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -69,8 +69,12 @@
/** Intent used to bind to the service */
private final Intent mIntent;
+ private static final int STATE_IDLE = 0; // no bind operation is ongoing
+ private static final int STATE_BINDING = 1; // someone is binding and waiting
+ private static final int STATE_PENDING = 2; // a bind is pending, but the caller is not waiting
+
@GuardedBy("mLock")
- private volatile boolean mIsBinding;
+ private int mBindState = STATE_IDLE;
@GuardedBy("mLock")
private IInstantAppResolver mRemoteInstance;
@@ -137,23 +141,17 @@
private IInstantAppResolver getRemoteInstanceLazy(String token)
throws ConnectionException, TimeoutException, InterruptedException {
- synchronized (mLock) {
- if (mRemoteInstance != null) {
- return mRemoteInstance;
- }
- long binderToken = Binder.clearCallingIdentity();
- try {
- bindLocked(token);
- } finally {
- Binder.restoreCallingIdentity(binderToken);
- }
- return mRemoteInstance;
+ long binderToken = Binder.clearCallingIdentity();
+ try {
+ return bind(token);
+ } finally {
+ Binder.restoreCallingIdentity(binderToken);
}
}
private void waitForBindLocked(String token) throws TimeoutException, InterruptedException {
final long startMillis = SystemClock.uptimeMillis();
- while (mIsBinding) {
+ while (mBindState != STATE_IDLE) {
if (mRemoteInstance != null) {
break;
}
@@ -166,40 +164,81 @@
}
}
- private void bindLocked(String token)
+ private IInstantAppResolver bind(String token)
throws ConnectionException, TimeoutException, InterruptedException {
- if (DEBUG_EPHEMERAL && mIsBinding && mRemoteInstance == null) {
- Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
- }
- try {
- waitForBindLocked(token);
- } catch (TimeoutException e) {
- if (DEBUG_EPHEMERAL) {
- Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
+ boolean doUnbind = false;
+ synchronized (mLock) {
+ if (mRemoteInstance != null) {
+ return mRemoteInstance;
}
- mContext.unbindService(mServiceConnection);
+
+ if (mBindState == STATE_PENDING) {
+ // there is a pending bind, let's see if we can use it.
+ if (DEBUG_EPHEMERAL) {
+ Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
+ }
+ try {
+ waitForBindLocked(token);
+ if (mRemoteInstance != null) {
+ return mRemoteInstance;
+ }
+ } catch (TimeoutException e) {
+ // nope, we might have to try a rebind.
+ doUnbind = true;
+ }
+ }
+
+ if (mBindState == STATE_BINDING) {
+ // someone was binding when we called bind(), or they raced ahead while we were
+ // waiting in the PENDING case; wait for their result instead. Last chance!
+ if (DEBUG_EPHEMERAL) {
+ Slog.i(TAG, "[" + token + "] Another thread is binding; waiting for connection");
+ }
+ waitForBindLocked(token);
+ // if the other thread's bindService() returned false, we could still have null.
+ if (mRemoteInstance != null) {
+ return mRemoteInstance;
+ }
+ throw new ConnectionException(ConnectionException.FAILURE_BIND);
+ }
+ mBindState = STATE_BINDING; // our time to shine! :)
}
- if (mRemoteInstance != null) {
- return;
- }
- mIsBinding = true;
- if (DEBUG_EPHEMERAL) {
- Slog.v(TAG, "[" + token + "] Binding to instant app resolver");
- }
+
+ // only one thread can be here at a time (the one that set STATE_BINDING)
boolean wasBound = false;
+ IInstantAppResolver instance = null;
try {
+ if (doUnbind) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
+ }
+ mContext.unbindService(mServiceConnection);
+ }
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "[" + token + "] Binding to instant app resolver");
+ }
final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
wasBound = mContext
.bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM);
if (wasBound) {
- waitForBindLocked(token);
+ synchronized (mLock) {
+ waitForBindLocked(token);
+ instance = mRemoteInstance;
+ return instance;
+ }
} else {
Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent);
throw new ConnectionException(ConnectionException.FAILURE_BIND);
}
} finally {
- mIsBinding = wasBound && mRemoteInstance == null;
- mLock.notifyAll();
+ synchronized (mLock) {
+ if (wasBound && instance == null) {
+ mBindState = STATE_PENDING;
+ } else {
+ mBindState = STATE_IDLE;
+ }
+ mLock.notifyAll();
+ }
}
}
@@ -255,7 +294,9 @@
}
synchronized (mLock) {
mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
- mIsBinding = false;
+ if (mBindState == STATE_PENDING) {
+ mBindState = STATE_IDLE;
+ }
try {
service.linkToDeath(EphemeralResolverConnection.this, 0 /*flags*/);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index d0d306c..f50d0d7 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -194,6 +194,7 @@
requestObj.userId,
packageName,
splitName,
+ requestObj.responseObj.installFailureActivity,
versionCode,
token,
false /*needsPhaseTwo*/);
@@ -239,6 +240,7 @@
int userId,
@NonNull String instantAppPackageName,
@Nullable String instantAppSplitName,
+ @Nullable ComponentName installFailureActivity,
int versionCode,
@Nullable String token,
boolean needsPhaseTwo) {
@@ -260,15 +262,25 @@
// We have all of the data we need; just start the installer without a second phase
if (!needsPhaseTwo) {
// Intent that is launched if the package couldn't be installed for any reason.
- if (failureIntent != null) {
+ if (failureIntent != null || installFailureActivity != null) {
try {
+ final Intent onFailureIntent;
+ if (installFailureActivity != null) {
+ onFailureIntent = new Intent();
+ onFailureIntent.setComponent(installFailureActivity);
+ onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
+ onFailureIntent.putExtra(Intent.EXTRA_INTENT, origIntent);
+ } else {
+ onFailureIntent = failureIntent;
+ }
final IIntentSender failureIntentTarget = ActivityManager.getService()
.getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
- new Intent[] { failureIntent },
+ new Intent[] { onFailureIntent },
new String[] { resolvedType },
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+ PendingIntent.FLAG_CANCEL_CURRENT
+ | PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_IMMUTABLE,
null /*bOptions*/, userId);
intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE,
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 241d76f..da6e26e 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -318,7 +318,7 @@
optimizer.performDexOpt(pkg, libraryDependencies,
null /* ISAs */,
null /* CompilerStats.PackageStats */,
- mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName),
+ mPackageManagerService.getDexManager().getPackageUseInfoOrDefault(pkg.packageName),
new DexoptOptions(pkg.packageName, compilationReason,
DexoptOptions.DEXOPT_BOOT_COMPLETE));
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 41bc7f2..2f4f5ab 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -31,14 +31,16 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.dex.DexoptUtils;
+import com.android.server.pm.dex.PackageDexUsage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
import dalvik.system.DexFile;
@@ -112,7 +114,7 @@
*/
int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
String[] instructionSets, CompilerStats.PackageStats packageStats,
- boolean isUsedByOtherApps, DexoptOptions options) {
+ PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
if (!canOptimizePackage(pkg)) {
return DEX_OPT_SKIPPED;
}
@@ -120,7 +122,7 @@
final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
try {
return performDexOptLI(pkg, sharedLibraries, instructionSets,
- packageStats, isUsedByOtherApps, options);
+ packageStats, packageUseInfo, options);
} finally {
releaseWakeLockLI(acquireTime);
}
@@ -134,21 +136,13 @@
@GuardedBy("mInstallLock")
private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
- boolean isUsedByOtherApps, DexoptOptions options) {
+ PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
final List<String> paths = pkg.getAllCodePaths();
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
- final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
- options.getCompilerFilter(), isUsedByOtherApps);
- final boolean profileUpdated = options.isCheckForProfileUpdates() &&
- isProfileUpdated(pkg, sharedGid, compilerFilter);
-
- // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
- final int dexoptFlags = getDexFlags(pkg, compilerFilter, options.isBootComplete());
-
// Get the class loader context dependencies.
// For each code path in the package, this array contains the class loader context that
// needs to be passed to dexopt in order to ensure correct optimizations.
@@ -172,6 +166,17 @@
}
}
+ final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary()
+ || packageUseInfo.isUsedByOtherApps(path);
+ final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
+ options.getCompilerFilter(), isUsedByOtherApps);
+ final boolean profileUpdated = options.isCheckForProfileUpdates() &&
+ isProfileUpdated(pkg, sharedGid, compilerFilter);
+
+ // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct
+ // flags.
+ final int dexoptFlags = getDexFlags(pkg, compilerFilter, options.isBootComplete());
+
for (String dexCodeIsa : dexCodeInstructionSets) {
int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter,
profileUpdated, classLoaderContexts[i], dexoptFlags, sharedGid,
@@ -251,13 +256,12 @@
* throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though
* that seems wasteful.
*/
- public int dexOptSecondaryDexPath(ApplicationInfo info, String path, Set<String> isas,
- String compilerFilter, boolean isUsedByOtherApps, boolean downgrade) {
+ public int dexOptSecondaryDexPath(ApplicationInfo info, String path,
+ PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) {
synchronized (mInstallLock) {
final long acquireTime = acquireWakeLockLI(info.uid);
try {
- return dexOptSecondaryDexPathLI(info, path, isas, compilerFilter,
- isUsedByOtherApps, downgrade);
+ return dexOptSecondaryDexPathLI(info, path, dexUseInfo, options);
} finally {
releaseWakeLockLI(acquireTime);
}
@@ -298,9 +302,16 @@
}
@GuardedBy("mInstallLock")
- private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas,
- String compilerFilter, boolean isUsedByOtherApps, boolean downgrade) {
- compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
+ private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path,
+ PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) {
+ if (options.isDexoptOnlySharedDex() && !dexUseInfo.isUsedByOtherApps()) {
+ // We are asked to optimize only the dex files used by other apps and this is not
+ // on of them: skip it.
+ return DEX_OPT_SKIPPED;
+ }
+
+ String compilerFilter = getRealCompilerFilter(info, options.getCompilerFilter(),
+ dexUseInfo.isUsedByOtherApps());
// Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
// Secondary dex files are currently not compiled at boot.
int dexoptFlags = getDexFlags(info, compilerFilter, /* bootComplete */ true)
@@ -317,20 +328,32 @@
return DEX_OPT_FAILED;
}
Log.d(TAG, "Running dexopt on: " + path
- + " pkg=" + info.packageName + " isa=" + isas
+ + " pkg=" + info.packageName + " isa=" + dexUseInfo.getLoaderIsas()
+ " dexoptFlags=" + printDexoptFlags(dexoptFlags)
+ " target-filter=" + compilerFilter);
+ String classLoaderContext;
+ if (dexUseInfo.isUnknownClassLoaderContext() ||
+ dexUseInfo.isUnsupportedClassLoaderContext() ||
+ dexUseInfo.isVariableClassLoaderContext()) {
+ // If we have an unknown (not yet set), unsupported (custom class loaders), or a
+ // variable class loader chain, compile without a context and mark the oat file with
+ // SKIP_SHARED_LIBRARY_CHECK. Note that his might lead to a incorrect compilation.
+ // TODO(calin): We should just extract in this case.
+ classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+ } else {
+ classLoaderContext = dexUseInfo.getClassLoaderContext();
+ }
try {
- for (String isa : isas) {
+ for (String isa : dexUseInfo.getLoaderIsas()) {
// Reuse the same dexopt path as for the primary apks. We don't need all the
// arguments as some (dexopNeeded and oatDir) will be computed by installd because
// system server cannot read untrusted app content.
// TODO(calin): maybe add a separate call.
mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0,
/*oatDir*/ null, dexoptFlags,
- compilerFilter, info.volumeUuid, SKIP_SHARED_LIBRARY_CHECK, info.seInfoUser,
- downgrade);
+ compilerFilter, info.volumeUuid, classLoaderContext, info.seInfoUser,
+ options.isDowngrade());
}
return DEX_OPT_PERFORMED;
@@ -358,26 +381,60 @@
/**
* Dumps the dexopt state of the given package {@code pkg} to the given {@code PrintWriter}.
*/
- void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg) {
+ void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg,
+ PackageDexUsage.PackageUseInfo useInfo) {
final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
- for (String instructionSet : dexCodeInstructionSets) {
- pw.println("Instruction Set: " + instructionSet);
- pw.increaseIndent();
- for (String path : paths) {
- String status = null;
- try {
- status = DexFile.getDexFileStatus(path, instructionSet);
- } catch (IOException ioe) {
- status = "[Exception]: " + ioe.getMessage();
- }
- pw.println("path: " + path);
- pw.println("status: " + status);
- }
- pw.decreaseIndent();
+ for (String path : paths) {
+ pw.println("path: " + path);
+ pw.increaseIndent();
+
+ for (String isa : dexCodeInstructionSets) {
+ String status = null;
+ try {
+ status = DexFile.getDexFileStatus(path, isa);
+ } catch (IOException ioe) {
+ status = "[Exception]: " + ioe.getMessage();
+ }
+ pw.println(isa + ": " + status);
+ }
+
+ if (useInfo.isUsedByOtherApps(path)) {
+ pw.println("used be other apps: " + useInfo.getLoadingPackages(path));
+ }
+
+ Map<String, PackageDexUsage.DexUseInfo> dexUseInfoMap = useInfo.getDexUseInfoMap();
+
+ if (!dexUseInfoMap.isEmpty()) {
+ pw.println("known secondary dex files:");
+ pw.increaseIndent();
+ for (Map.Entry<String, PackageDexUsage.DexUseInfo> e : dexUseInfoMap.entrySet()) {
+ String dex = e.getKey();
+ PackageDexUsage.DexUseInfo dexUseInfo = e.getValue();
+ pw.println(dex);
+ pw.increaseIndent();
+ for (String isa : dexUseInfo.getLoaderIsas()) {
+ String status = null;
+ try {
+ status = DexFile.getDexFileStatus(path, isa);
+ } catch (IOException ioe) {
+ status = "[Exception]: " + ioe.getMessage();
+ }
+ pw.println(isa + ": " + status);
+ }
+
+ pw.println("class loader context: " + dexUseInfo.getClassLoaderContext());
+ if (dexUseInfo.isUsedByOtherApps()) {
+ pw.println("used be other apps: " + dexUseInfo.getLoadingPackages());
+ }
+ pw.decreaseIndent();
+ }
+ pw.decreaseIndent();
+ }
+ pw.decreaseIndent();
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index bab7011..c3b93b4 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -16,17 +16,6 @@
package com.android.server.pm;
-import static com.android.internal.util.XmlUtils.readBitmapAttribute;
-import static com.android.internal.util.XmlUtils.readBooleanAttribute;
-import static com.android.internal.util.XmlUtils.readIntAttribute;
-import static com.android.internal.util.XmlUtils.readLongAttribute;
-import static com.android.internal.util.XmlUtils.readStringAttribute;
-import static com.android.internal.util.XmlUtils.readUriAttribute;
-import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
-import static com.android.internal.util.XmlUtils.writeIntAttribute;
-import static com.android.internal.util.XmlUtils.writeLongAttribute;
-import static com.android.internal.util.XmlUtils.writeStringAttribute;
-import static com.android.internal.util.XmlUtils.writeUriAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -54,8 +43,6 @@
import android.content.pm.ParceledListSlice;
import android.content.pm.VersionedPackage;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -84,9 +71,6 @@
import android.util.SparseIntArray;
import android.util.Xml;
-import java.io.CharArrayWriter;
-import libcore.io.IoUtils;
-
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageHelper;
@@ -97,10 +81,13 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -125,32 +112,6 @@
/** XML constants used in {@link #mSessionsFile} */
private static final String TAG_SESSIONS = "sessions";
- private static final String TAG_SESSION = "session";
- private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
- private static final String ATTR_SESSION_ID = "sessionId";
- private static final String ATTR_USER_ID = "userId";
- private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
- private static final String ATTR_INSTALLER_UID = "installerUid";
- private static final String ATTR_CREATED_MILLIS = "createdMillis";
- private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
- private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid";
- private static final String ATTR_PREPARED = "prepared";
- private static final String ATTR_SEALED = "sealed";
- private static final String ATTR_MODE = "mode";
- private static final String ATTR_INSTALL_FLAGS = "installFlags";
- private static final String ATTR_INSTALL_LOCATION = "installLocation";
- private static final String ATTR_SIZE_BYTES = "sizeBytes";
- private static final String ATTR_APP_PACKAGE_NAME = "appPackageName";
- @Deprecated
- private static final String ATTR_APP_ICON = "appIcon";
- private static final String ATTR_APP_LABEL = "appLabel";
- private static final String ATTR_ORIGINATING_URI = "originatingUri";
- private static final String ATTR_ORIGINATING_UID = "originatingUid";
- private static final String ATTR_REFERRER_URI = "referrerUri";
- private static final String ATTR_ABI_OVERRIDE = "abiOverride";
- private static final String ATTR_VOLUME_UUID = "volumeUuid";
- private static final String ATTR_NAME = "name";
- private static final String ATTR_INSTALL_REASON = "installRason";
/** Automatically destroy sessions older than this */
private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS;
@@ -357,8 +318,10 @@
while ((type = in.next()) != END_DOCUMENT) {
if (type == START_TAG) {
final String tag = in.getName();
- if (TAG_SESSION.equals(tag)) {
- final PackageInstallerSession session = readSessionLocked(in);
+ if (PackageInstallerSession.TAG_SESSION.equals(tag)) {
+ final PackageInstallerSession session = PackageInstallerSession.
+ readFromXml(in, mInternalCallback, mContext, mPm,
+ mInstallThread.getLooper(), mSessionsDir);
final long age = System.currentTimeMillis() - session.createdMillis;
final boolean valid;
@@ -397,53 +360,10 @@
session.dump(pw);
mHistoricalSessions.add(writer.toString());
+ int installerUid = session.getInstallerUid();
// Increment the number of sessions by this installerUid.
- mHistoricalSessionsByInstaller.put(
- session.installerUid,
- mHistoricalSessionsByInstaller.get(session.installerUid) + 1);
- }
-
- private PackageInstallerSession readSessionLocked(XmlPullParser in) throws IOException,
- XmlPullParserException {
- final int sessionId = readIntAttribute(in, ATTR_SESSION_ID);
- final int userId = readIntAttribute(in, ATTR_USER_ID);
- final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
- final int installerUid = readIntAttribute(in, ATTR_INSTALLER_UID, mPm.getPackageUid(
- installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
- final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
- final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR);
- final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null;
- final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID);
- final boolean prepared = readBooleanAttribute(in, ATTR_PREPARED, true);
- final boolean sealed = readBooleanAttribute(in, ATTR_SEALED);
-
- final SessionParams params = new SessionParams(
- SessionParams.MODE_INVALID);
- params.mode = readIntAttribute(in, ATTR_MODE);
- params.installFlags = readIntAttribute(in, ATTR_INSTALL_FLAGS);
- params.installLocation = readIntAttribute(in, ATTR_INSTALL_LOCATION);
- params.sizeBytes = readLongAttribute(in, ATTR_SIZE_BYTES);
- params.appPackageName = readStringAttribute(in, ATTR_APP_PACKAGE_NAME);
- params.appIcon = readBitmapAttribute(in, ATTR_APP_ICON);
- params.appLabel = readStringAttribute(in, ATTR_APP_LABEL);
- params.originatingUri = readUriAttribute(in, ATTR_ORIGINATING_URI);
- params.originatingUid =
- readIntAttribute(in, ATTR_ORIGINATING_UID, SessionParams.UID_UNKNOWN);
- params.referrerUri = readUriAttribute(in, ATTR_REFERRER_URI);
- params.abiOverride = readStringAttribute(in, ATTR_ABI_OVERRIDE);
- params.volumeUuid = readStringAttribute(in, ATTR_VOLUME_UUID);
- params.grantedRuntimePermissions = readGrantedRuntimePermissions(in);
- params.installReason = readIntAttribute(in, ATTR_INSTALL_REASON);
-
- final File appIconFile = buildAppIconFile(sessionId);
- if (appIconFile.exists()) {
- params.appIcon = BitmapFactory.decodeFile(appIconFile.getAbsolutePath());
- params.appIconLastModified = appIconFile.lastModified();
- }
-
- return new PackageInstallerSession(mInternalCallback, mContext, mPm,
- mInstallThread.getLooper(), sessionId, userId, installerPackageName, installerUid,
- params, createdMillis, stageDir, stageCid, prepared, sealed);
+ mHistoricalSessionsByInstaller.put(installerUid,
+ mHistoricalSessionsByInstaller.get(installerUid) + 1);
}
private void writeSessionsLocked() {
@@ -460,7 +380,7 @@
final int size = mSessions.size();
for (int i = 0; i < size; i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
- writeSessionLocked(out, session);
+ session.write(out, mSessionsDir);
}
out.endTag(null, TAG_SESSIONS);
out.endDocument();
@@ -473,106 +393,6 @@
}
}
- private void writeSessionLocked(XmlSerializer out, PackageInstallerSession session)
- throws IOException {
- final SessionParams params = session.params;
-
- out.startTag(null, TAG_SESSION);
-
- writeIntAttribute(out, ATTR_SESSION_ID, session.sessionId);
- writeIntAttribute(out, ATTR_USER_ID, session.userId);
- writeStringAttribute(out, ATTR_INSTALLER_PACKAGE_NAME,
- session.installerPackageName);
- writeIntAttribute(out, ATTR_INSTALLER_UID, session.installerUid);
- writeLongAttribute(out, ATTR_CREATED_MILLIS, session.createdMillis);
- if (session.stageDir != null) {
- writeStringAttribute(out, ATTR_SESSION_STAGE_DIR,
- session.stageDir.getAbsolutePath());
- }
- if (session.stageCid != null) {
- writeStringAttribute(out, ATTR_SESSION_STAGE_CID, session.stageCid);
- }
- writeBooleanAttribute(out, ATTR_PREPARED, session.isPrepared());
- writeBooleanAttribute(out, ATTR_SEALED, session.isSealed());
-
- writeIntAttribute(out, ATTR_MODE, params.mode);
- writeIntAttribute(out, ATTR_INSTALL_FLAGS, params.installFlags);
- writeIntAttribute(out, ATTR_INSTALL_LOCATION, params.installLocation);
- writeLongAttribute(out, ATTR_SIZE_BYTES, params.sizeBytes);
- writeStringAttribute(out, ATTR_APP_PACKAGE_NAME, params.appPackageName);
- writeStringAttribute(out, ATTR_APP_LABEL, params.appLabel);
- writeUriAttribute(out, ATTR_ORIGINATING_URI, params.originatingUri);
- writeIntAttribute(out, ATTR_ORIGINATING_UID, params.originatingUid);
- writeUriAttribute(out, ATTR_REFERRER_URI, params.referrerUri);
- writeStringAttribute(out, ATTR_ABI_OVERRIDE, params.abiOverride);
- writeStringAttribute(out, ATTR_VOLUME_UUID, params.volumeUuid);
- writeIntAttribute(out, ATTR_INSTALL_REASON, params.installReason);
-
- // Persist app icon if changed since last written
- final File appIconFile = buildAppIconFile(session.sessionId);
- if (params.appIcon == null && appIconFile.exists()) {
- appIconFile.delete();
- } else if (params.appIcon != null
- && appIconFile.lastModified() != params.appIconLastModified) {
- if (LOGD) Slog.w(TAG, "Writing changed icon " + appIconFile);
- FileOutputStream os = null;
- try {
- os = new FileOutputStream(appIconFile);
- params.appIcon.compress(CompressFormat.PNG, 90, os);
- } catch (IOException e) {
- Slog.w(TAG, "Failed to write icon " + appIconFile + ": " + e.getMessage());
- } finally {
- IoUtils.closeQuietly(os);
- }
-
- params.appIconLastModified = appIconFile.lastModified();
- }
-
- writeGrantedRuntimePermissions(out, params.grantedRuntimePermissions);
-
- out.endTag(null, TAG_SESSION);
- }
-
- private static void writeGrantedRuntimePermissions(XmlSerializer out,
- String[] grantedRuntimePermissions) throws IOException {
- if (grantedRuntimePermissions != null) {
- for (String permission : grantedRuntimePermissions) {
- out.startTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
- writeStringAttribute(out, ATTR_NAME, permission);
- out.endTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
- }
- }
- }
-
- private static String[] readGrantedRuntimePermissions(XmlPullParser in)
- throws IOException, XmlPullParserException {
- List<String> permissions = null;
-
- final int outerDepth = in.getDepth();
- int type;
- while ((type = in.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || in.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- if (TAG_GRANTED_RUNTIME_PERMISSION.equals(in.getName())) {
- String permission = readStringAttribute(in, ATTR_NAME);
- if (permissions == null) {
- permissions = new ArrayList<>();
- }
- permissions.add(permission);
- }
- }
-
- if (permissions == null) {
- return null;
- }
-
- String[] permissionsArray = new String[permissions.size()];
- permissions.toArray(permissionsArray);
- return permissionsArray;
- }
-
private File buildAppIconFile(int sessionId) {
return new File(mSessionsDir, "app_icon." + sessionId + ".png");
}
@@ -885,9 +705,11 @@
synchronized (mSessions) {
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
- if (Objects.equals(session.installerPackageName, installerPackageName)
+
+ SessionInfo info = session.generateInfo(false);
+ if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
&& session.userId == userId) {
- result.add(session.generateInfo(false));
+ result.add(info);
}
}
}
@@ -962,7 +784,7 @@
final int size = sessions.size();
for (int i = 0; i < size; i++) {
final PackageInstallerSession session = sessions.valueAt(i);
- if (session.installerUid == installerUid) {
+ if (session.getInstallerUid() == installerUid) {
count++;
}
}
@@ -974,7 +796,7 @@
if (callingUid == Process.ROOT_UID) {
return true;
} else {
- return (session != null) && (callingUid == session.installerUid);
+ return (session != null) && (callingUid == session.getInstallerUid());
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5823771..d492590 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -25,9 +25,22 @@
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_WRONLY;
+import static com.android.internal.util.XmlUtils.readBitmapAttribute;
+import static com.android.internal.util.XmlUtils.readBooleanAttribute;
+import static com.android.internal.util.XmlUtils.readIntAttribute;
+import static com.android.internal.util.XmlUtils.readLongAttribute;
+import static com.android.internal.util.XmlUtils.readStringAttribute;
+import static com.android.internal.util.XmlUtils.readUriAttribute;
+import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
+import static com.android.internal.util.XmlUtils.writeIntAttribute;
+import static com.android.internal.util.XmlUtils.writeLongAttribute;
+import static com.android.internal.util.XmlUtils.writeStringAttribute;
+import static com.android.internal.util.XmlUtils.writeUriAttribute;
import static com.android.server.pm.PackageInstallerService.prepareExternalStageCid;
import static com.android.server.pm.PackageInstallerService.prepareStageDir;
+import android.Manifest;
+import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
@@ -45,6 +58,8 @@
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.Signature;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Bundle;
import android.os.FileBridge;
@@ -53,6 +68,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
@@ -80,9 +96,14 @@
import libcore.io.IoUtils;
import libcore.io.Libcore;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileFilter;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.util.ArrayList;
@@ -97,6 +118,34 @@
private static final int MSG_COMMIT = 0;
+ /** XML constants used for persisting a session */
+ static final String TAG_SESSION = "session";
+ private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
+ private static final String ATTR_SESSION_ID = "sessionId";
+ private static final String ATTR_USER_ID = "userId";
+ private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
+ private static final String ATTR_INSTALLER_UID = "installerUid";
+ private static final String ATTR_CREATED_MILLIS = "createdMillis";
+ private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir";
+ private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid";
+ private static final String ATTR_PREPARED = "prepared";
+ private static final String ATTR_SEALED = "sealed";
+ private static final String ATTR_MODE = "mode";
+ private static final String ATTR_INSTALL_FLAGS = "installFlags";
+ private static final String ATTR_INSTALL_LOCATION = "installLocation";
+ private static final String ATTR_SIZE_BYTES = "sizeBytes";
+ private static final String ATTR_APP_PACKAGE_NAME = "appPackageName";
+ @Deprecated
+ private static final String ATTR_APP_ICON = "appIcon";
+ private static final String ATTR_APP_LABEL = "appLabel";
+ private static final String ATTR_ORIGINATING_URI = "originatingUri";
+ private static final String ATTR_ORIGINATING_UID = "originatingUid";
+ private static final String ATTR_REFERRER_URI = "referrerUri";
+ private static final String ATTR_ABI_OVERRIDE = "abiOverride";
+ private static final String ATTR_VOLUME_UUID = "volumeUuid";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_INSTALL_REASON = "installRason";
+
// TODO: enforce INSTALL_ALLOW_TEST
// TODO: enforce INSTALL_ALLOW_DOWNGRADE
@@ -104,12 +153,9 @@
private final Context mContext;
private final PackageManagerService mPm;
private final Handler mHandler;
- private final boolean mIsInstallerDeviceOwner;
final int sessionId;
final int userId;
- final String installerPackageName;
- final int installerUid;
final SessionParams params;
final long createdMillis;
final int defaultContainerGid;
@@ -122,6 +168,17 @@
private final Object mLock = new Object();
+ /** Uid of the creator of this session. */
+ private final int mOriginalInstallerUid;
+
+ /** Package of the owner of the installer session */
+ @GuardedBy("mLock")
+ private String mInstallerPackageName;
+
+ /** Uid of the owner of the installer session */
+ @GuardedBy("mLock")
+ private int mInstallerUid;
+
@GuardedBy("mLock")
private float mClientProgress = 0;
@GuardedBy("mLock")
@@ -132,18 +189,25 @@
@GuardedBy("mLock")
private float mReportedProgress = -1;
+ /** State of the session. */
@GuardedBy("mLock")
private boolean mPrepared = false;
@GuardedBy("mLock")
private boolean mSealed = false;
@GuardedBy("mLock")
- private boolean mPermissionsAccepted = false;
+ private boolean mCommitted = false;
@GuardedBy("mLock")
private boolean mRelinquished = false;
@GuardedBy("mLock")
private boolean mDestroyed = false;
+ /** Permissions have been accepted by the user (see {@link #setPermissionsResult}) */
+ @GuardedBy("mLock")
+ private boolean mPermissionsManuallyAccepted = false;
+
+ @GuardedBy("mLock")
private int mFinalStatus;
+ @GuardedBy("mLock")
private String mFinalMessage;
@GuardedBy("mLock")
@@ -155,9 +219,13 @@
private IPackageInstallObserver2 mRemoteObserver;
/** Fields derived from commit parsing */
+ @GuardedBy("mLock")
private String mPackageName;
+ @GuardedBy("mLock")
private int mVersionCode;
+ @GuardedBy("mLock")
private Signature[] mSignatures;
+ @GuardedBy("mLock")
private Certificate[][] mCertificates;
/**
@@ -205,32 +273,61 @@
private final Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
- // Cache package manager data without the lock held
- final PackageInfo pkgInfo = mPm.getPackageInfo(
- params.appPackageName, PackageManager.GET_SIGNATURES
- | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
- final ApplicationInfo appInfo = mPm.getApplicationInfo(
- params.appPackageName, 0, userId);
-
synchronized (mLock) {
if (msg.obj != null) {
mRemoteObserver = (IPackageInstallObserver2) msg.obj;
}
-
try {
- commitLocked(pkgInfo, appInfo);
+ commitLocked();
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
destroyInternal();
dispatchSessionFinished(e.error, completeMsg, null);
}
-
- return true;
}
+
+ return true;
}
};
+ /**
+ * @return {@code true} iff the installing is app an device owner?
+ */
+ private boolean isInstallerDeviceOwnerLocked() {
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+
+ return (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser(
+ mInstallerPackageName);
+ }
+
+ /**
+ * Checks if the permissions still need to be confirmed.
+ *
+ * <p>This is dependant on the identity of the installer, hence this cannot be cached if the
+ * installer might still {@link #transfer(String) change}.
+ *
+ * @return {@code true} iff we need to ask to confirm the permissions?
+ */
+ private boolean needToAskForPermissionsLocked() {
+ if (mPermissionsManuallyAccepted) {
+ return false;
+ }
+
+ final boolean isPermissionGranted =
+ (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ mInstallerUid) == PackageManager.PERMISSION_GRANTED);
+ final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
+ final boolean forcePermissionPrompt =
+ (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0;
+
+ // Device owners are allowed to silently install packages, so the permission check is
+ // waived if the installer is the device owner.
+ return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot
+ || isInstallerDeviceOwnerLocked());
+ }
+
public PackageInstallerSession(PackageInstallerService.InternalCallback callback,
Context context, PackageManagerService pm, Looper looper, int sessionId, int userId,
String installerPackageName, int installerUid, SessionParams params, long createdMillis,
@@ -242,8 +339,9 @@
this.sessionId = sessionId;
this.userId = userId;
- this.installerPackageName = installerPackageName;
- this.installerUid = installerUid;
+ mOriginalInstallerUid = installerUid;
+ mInstallerPackageName = installerPackageName;
+ mInstallerUid = installerUid;
this.params = params;
this.createdMillis = createdMillis;
this.stageDir = stageDir;
@@ -257,26 +355,6 @@
mPrepared = prepared;
mSealed = sealed;
- // Device owners are allowed to silently install packages, so the permission check is
- // waived if the installer is the device owner.
- DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- final boolean isPermissionGranted =
- (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
- == PackageManager.PERMISSION_GRANTED);
- final boolean isInstallerRoot = (installerUid == Process.ROOT_UID);
- final boolean forcePermissionPrompt =
- (params.installFlags & PackageManager.INSTALL_FORCE_PERMISSION_PROMPT) != 0;
- mIsInstallerDeviceOwner = (dpm != null) && dpm.isDeviceOwnerAppOnCallingUser(
- installerPackageName);
- if ((isPermissionGranted
- || isInstallerRoot
- || mIsInstallerDeviceOwner)
- && !forcePermissionPrompt) {
- mPermissionsAccepted = true;
- } else {
- mPermissionsAccepted = false;
- }
final long identity = Binder.clearCallingIdentity();
try {
final int uid = mPm.getPackageUid(PackageManagerService.DEFAULT_CONTAINER_PACKAGE,
@@ -295,7 +373,7 @@
final SessionInfo info = new SessionInfo();
synchronized (mLock) {
info.sessionId = sessionId;
- info.installerPackageName = installerPackageName;
+ info.installerPackageName = mInstallerPackageName;
info.resolvedBaseCodePath = (mResolvedBaseFile != null) ?
mResolvedBaseFile.getAbsolutePath() : null;
info.progress = mProgress;
@@ -310,6 +388,13 @@
info.appIcon = params.appIcon;
}
info.appLabel = params.appLabel;
+
+ info.installLocation = params.installLocation;
+ info.originatingUri = params.originatingUri;
+ info.originatingUid = params.originatingUid;
+ info.referrerUri = params.referrerUri;
+ info.grantedRuntimePermissions = params.grantedRuntimePermissions;
+ info.installFlags = params.installFlags;
}
return info;
}
@@ -326,14 +411,26 @@
}
}
- private void assertPreparedAndNotSealed(String cookie) {
- synchronized (mLock) {
- if (!mPrepared) {
- throw new IllegalStateException(cookie + " before prepared");
- }
- if (mSealed) {
- throw new SecurityException(cookie + " not allowed after commit");
- }
+ private void assertPreparedAndNotSealedLocked(String cookie) {
+ assertPreparedAndNotCommittedOrDestroyedLocked(cookie);
+ if (mSealed) {
+ throw new SecurityException(cookie + " not allowed after sealing");
+ }
+ }
+
+ private void assertPreparedAndNotCommittedOrDestroyedLocked(String cookie) {
+ assertPreparedAndNotDestroyedLocked(cookie);
+ if (mCommitted) {
+ throw new SecurityException(cookie + " not allowed after commit");
+ }
+ }
+
+ private void assertPreparedAndNotDestroyedLocked(String cookie) {
+ if (!mPrepared) {
+ throw new IllegalStateException(cookie + " before prepared");
+ }
+ if (mDestroyed) {
+ throw new SecurityException(cookie + " not allowed after destruction");
}
}
@@ -342,27 +439,27 @@
* might point at an ASEC mount point, which is why we delay path resolution
* until someone actively works with the session.
*/
- private File resolveStageDir() throws IOException {
- synchronized (mLock) {
- if (mResolvedStageDir == null) {
- if (stageDir != null) {
- mResolvedStageDir = stageDir;
+ private File resolveStageDirLocked() throws IOException {
+ if (mResolvedStageDir == null) {
+ if (stageDir != null) {
+ mResolvedStageDir = stageDir;
+ } else {
+ final String path = PackageHelper.getSdDir(stageCid);
+ if (path != null) {
+ mResolvedStageDir = new File(path);
} else {
- final String path = PackageHelper.getSdDir(stageCid);
- if (path != null) {
- mResolvedStageDir = new File(path);
- } else {
- throw new IOException("Failed to resolve path to container " + stageCid);
- }
+ throw new IOException("Failed to resolve path to container " + stageCid);
}
}
- return mResolvedStageDir;
}
+ return mResolvedStageDir;
}
@Override
public void setClientProgress(float progress) {
synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+
// Always publish first staging movement
final boolean forcePublish = (mClientProgress == 0);
mClientProgress = progress;
@@ -373,6 +470,8 @@
@Override
public void addClientProgress(float progress) {
synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+
setClientProgress(mClientProgress + progress);
}
}
@@ -390,11 +489,15 @@
@Override
public String[] getNames() {
- assertPreparedAndNotSealed("getNames");
- try {
- return resolveStageDir().list();
- } catch (IOException e) {
- throw ExceptionUtils.wrap(e);
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
+
+ try {
+ return resolveStageDirLocked().list();
+ } catch (IOException e) {
+ throw ExceptionUtils.wrap(e);
+ }
}
}
@@ -403,20 +506,26 @@
if (TextUtils.isEmpty(params.appPackageName)) {
throw new IllegalStateException("Must specify package name to remove a split");
}
- try {
- createRemoveSplitMarker(splitName);
- } catch (IOException e) {
- throw ExceptionUtils.wrap(e);
+
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotCommittedOrDestroyedLocked("removeSplit");
+
+ try {
+ createRemoveSplitMarkerLocked(splitName);
+ } catch (IOException e) {
+ throw ExceptionUtils.wrap(e);
+ }
}
}
- private void createRemoveSplitMarker(String splitName) throws IOException {
+ private void createRemoveSplitMarkerLocked(String splitName) throws IOException {
try {
final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;
if (!FileUtils.isValidExtFilename(markerName)) {
throw new IllegalArgumentException("Invalid marker: " + markerName);
}
- final File target = new File(resolveStageDir(), markerName);
+ final File target = new File(resolveStageDirLocked(), markerName);
target.createNewFile();
Os.chmod(target.getAbsolutePath(), 0 /*mode*/);
} catch (ErrnoException e) {
@@ -440,8 +549,10 @@
// will block any attempted install transitions.
final RevocableFileDescriptor fd;
final FileBridge bridge;
+ final File stageDir;
synchronized (mLock) {
- assertPreparedAndNotSealed("openWrite");
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotSealedLocked("openWrite");
if (PackageInstaller.ENABLE_REVOCABLE_FD) {
fd = new RevocableFileDescriptor();
@@ -452,6 +563,8 @@
bridge = new FileBridge();
mBridges.add(bridge);
}
+
+ stageDir = resolveStageDirLocked();
}
try {
@@ -462,7 +575,7 @@
final File target;
final long identity = Binder.clearCallingIdentity();
try {
- target = new File(resolveStageDir(), name);
+ target = new File(stageDir, name);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -500,55 +613,108 @@
@Override
public ParcelFileDescriptor openRead(String name) {
- try {
- return openReadInternal(name);
- } catch (IOException e) {
- throw ExceptionUtils.wrap(e);
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotCommittedOrDestroyedLocked("openRead");
+ try {
+ return openReadInternalLocked(name);
+ } catch (IOException e) {
+ throw ExceptionUtils.wrap(e);
+ }
}
}
- private ParcelFileDescriptor openReadInternal(String name) throws IOException {
- assertPreparedAndNotSealed("openRead");
-
+ private ParcelFileDescriptor openReadInternalLocked(String name) throws IOException {
try {
if (!FileUtils.isValidExtFilename(name)) {
throw new IllegalArgumentException("Invalid name: " + name);
}
- final File target = new File(resolveStageDir(), name);
-
+ final File target = new File(resolveStageDirLocked(), name);
final FileDescriptor targetFd = Libcore.os.open(target.getAbsolutePath(), O_RDONLY, 0);
return new ParcelFileDescriptor(targetFd);
-
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
}
}
+ /**
+ * Check if the caller is the owner of this session. Otherwise throw a
+ * {@link SecurityException}.
+ */
+ private void assertCallerIsOwnerOrRootLocked() {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid) {
+ throw new SecurityException("Session does not belong to uid " + callingUid);
+ }
+ }
+
+ /**
+ * If anybody is reading or writing data of the session, throw an {@link SecurityException}.
+ */
+ private void assertNoWriteFileTransfersOpenLocked() {
+ // Verify that all writers are hands-off
+ for (RevocableFileDescriptor fd : mFds) {
+ if (!fd.isRevoked()) {
+ throw new SecurityException("Files still open");
+ }
+ }
+ for (FileBridge bridge : mBridges) {
+ if (!bridge.isClosed()) {
+ throw new SecurityException("Files still open");
+ }
+ }
+ }
+
@Override
- public void commit(IntentSender statusReceiver) {
+ public void commit(IntentSender statusReceiver, boolean forTransfer) {
Preconditions.checkNotNull(statusReceiver);
+ // Cache package manager data without the lock held
+ final PackageInfo installedPkgInfo = mPm.getPackageInfo(
+ params.appPackageName, PackageManager.GET_SIGNATURES
+ | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
+
final boolean wasSealed;
synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotDestroyedLocked("commit");
+
+ if (forTransfer) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
+
+ if (mInstallerUid == mOriginalInstallerUid) {
+ throw new IllegalArgumentException("Session has not been transferred");
+ }
+ } else {
+ if (mInstallerUid != mOriginalInstallerUid) {
+ throw new IllegalArgumentException("Session has been transferred");
+ }
+ }
+
wasSealed = mSealed;
if (!mSealed) {
- // Verify that all writers are hands-off
- for (RevocableFileDescriptor fd : mFds) {
- if (!fd.isRevoked()) {
- throw new SecurityException("Files still open");
- }
+ try {
+ sealAndValidateLocked(installedPkgInfo);
+ } catch (PackageManagerException e) {
+ // Do now throw an exception here to stay compatible with O and older
+ destroyInternal();
+ dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
+ return;
}
- for (FileBridge bridge : mBridges) {
- if (!bridge.isClosed()) {
- throw new SecurityException("Files still open");
- }
- }
- mSealed = true;
}
// Client staging is fully done at this point
mClientProgress = 1f;
computeProgressLocked(true);
+
+ // This ongoing commit should keep session active, even though client
+ // will probably close their end.
+ mActiveCount.incrementAndGet();
+
+ mCommitted = true;
+ final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
+ mContext, statusReceiver, sessionId, isInstallerDeviceOwnerLocked(), userId);
+ mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
}
if (!wasSealed) {
@@ -557,17 +723,82 @@
// the session lock, since otherwise it's a lock inversion.
mCallback.onSessionSealedBlocking(this);
}
-
- // This ongoing commit should keep session active, even though client
- // will probably close their end.
- mActiveCount.incrementAndGet();
-
- final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(mContext,
- statusReceiver, sessionId, mIsInstallerDeviceOwner, userId);
- mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
}
- private void commitLocked(PackageInfo pkgInfo, ApplicationInfo appInfo)
+ /**
+ * Seal the session to prevent further modification and validate the contents of it.
+ *
+ * <p>The session will be sealed after calling this method even if it failed.
+ *
+ * @param pkgInfo The package info for {@link #params}.packagename
+ */
+ private void sealAndValidateLocked(PackageInfo pkgInfo)
+ throws PackageManagerException {
+ assertNoWriteFileTransfersOpenLocked();
+
+ mSealed = true;
+
+ // Verify that stage looks sane with respect to existing application.
+ // This currently only ensures packageName, versionCode, and certificate
+ // consistency.
+ validateInstallLocked(pkgInfo);
+
+ // Read transfers from the original owner stay open, but as the session's data
+ // cannot be modified anymore, there is no leak of information.
+ }
+
+ @Override
+ public void transfer(String packageName) {
+ Preconditions.checkNotNull(packageName);
+
+ ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId);
+ if (newOwnerAppInfo == null) {
+ throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
+ }
+
+ if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission(
+ Manifest.permission.INSTALL_PACKAGES, newOwnerAppInfo.uid)) {
+ throw new SecurityException("Destination package " + packageName + " does not have "
+ + "the " + Manifest.permission.INSTALL_PACKAGES + " permission");
+ }
+
+ // Cache package manager data without the lock held
+ final PackageInfo installedPkgInfo = mPm.getPackageInfo(
+ params.appPackageName, PackageManager.GET_SIGNATURES
+ | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
+
+ // Only install flags that can be verified by the app the session is transferred to are
+ // allowed. The parameters can be read via PackageInstaller.SessionInfo.
+ if (!params.areHiddenOptionsSet()) {
+ throw new SecurityException("Can only transfer sessions that use public options");
+ }
+
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+ assertPreparedAndNotSealedLocked("transfer");
+
+ try {
+ sealAndValidateLocked(installedPkgInfo);
+ } catch (PackageManagerException e) {
+ throw new IllegalArgumentException("Package is not valid", e);
+ }
+
+ if (!mPackageName.equals(mInstallerPackageName)) {
+ throw new SecurityException("Can only transfer sessions that update the original "
+ + "installer");
+ }
+
+ mInstallerPackageName = packageName;
+ mInstallerUid = newOwnerAppInfo.uid;
+ }
+
+ // Persist the fact that we've sealed ourselves to prevent
+ // mutations of any hard links we create. We do this without holding
+ // the session lock, since otherwise it's a lock inversion.
+ mCallback.onSessionSealedBlocking(this);
+ }
+
+ private void commitLocked()
throws PackageManagerException {
if (mDestroyed) {
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
@@ -577,22 +808,17 @@
}
try {
- resolveStageDir();
+ resolveStageDirLocked();
} catch (IOException e) {
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
"Failed to resolve stage location", e);
}
- // Verify that stage looks sane with respect to existing application.
- // This currently only ensures packageName, versionCode, and certificate
- // consistency.
- validateInstallLocked(pkgInfo, appInfo);
-
Preconditions.checkNotNull(mPackageName);
Preconditions.checkNotNull(mSignatures);
Preconditions.checkNotNull(mResolvedBaseFile);
- if (!mPermissionsAccepted) {
+ if (needToAskForPermissionsLocked()) {
// User needs to accept permissions; give installer an intent they
// can use to involve user.
final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_PERMISSIONS);
@@ -605,7 +831,7 @@
// Commit was keeping session marked as active until now; release
// that extra refcount so session appears idle.
- close();
+ closeInternal(false);
return;
}
@@ -622,7 +848,7 @@
if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
try {
final List<File> fromFiles = mResolvedInheritedFiles;
- final File toDir = resolveStageDir();
+ final File toDir = resolveStageDirLocked();
if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
@@ -683,7 +909,7 @@
mRelinquished = true;
mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params,
- installerPackageName, installerUid, user, mCertificates);
+ mInstallerPackageName, mInstallerUid, user, mCertificates);
}
/**
@@ -698,8 +924,7 @@
* Note that upgrade compatibility is still performed by
* {@link PackageManagerService}.
*/
- private void validateInstallLocked(PackageInfo pkgInfo, ApplicationInfo appInfo)
- throws PackageManagerException {
+ private void validateInstallLocked(PackageInfo pkgInfo) throws PackageManagerException {
mPackageName = null;
mVersionCode = -1;
mSignatures = null;
@@ -752,7 +977,7 @@
mCertificates = apk.certificates;
}
- assertApkConsistent(String.valueOf(addedFile), apk);
+ assertApkConsistentLocked(String.valueOf(addedFile), apk);
// Take this opportunity to enforce uniform naming
final String targetName;
@@ -807,13 +1032,14 @@
} else {
// Partial installs must be consistent with existing install
- if (appInfo == null) {
+ if (pkgInfo == null || pkgInfo.applicationInfo == null) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Missing existing base package for " + mPackageName);
}
final PackageLite existing;
final ApkLite existingBase;
+ ApplicationInfo appInfo = pkgInfo.applicationInfo;
try {
existing = PackageParser.parsePackageLite(new File(appInfo.getCodePath()), 0);
existingBase = PackageParser.parseApkLite(new File(appInfo.getBaseCodePath()),
@@ -822,7 +1048,7 @@
throw PackageManagerException.from(e);
}
- assertApkConsistent("Existing base", existingBase);
+ assertApkConsistentLocked("Existing base", existingBase);
// Inherit base if not overridden
if (mResolvedBaseFile == null) {
@@ -878,7 +1104,7 @@
}
}
- private void assertApkConsistent(String tag, ApkLite apk)
+ private void assertApkConsistentLocked(String tag, ApkLite apk)
throws PackageManagerException {
if (!mPackageName.equals(apk.packageName)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
@@ -959,6 +1185,15 @@
return true;
}
+ /**
+ * @return the uid of the owner this session
+ */
+ public int getInstallerUid() {
+ synchronized (mLock) {
+ return mInstallerUid;
+ }
+ }
+
private static String getRelativePath(File file, File base) throws IOException {
final String pathStr = file.getAbsolutePath();
final String baseStr = base.getAbsolutePath();
@@ -1106,9 +1341,9 @@
if (accepted) {
// Mark and kick off another install pass
synchronized (mLock) {
- mPermissionsAccepted = true;
+ mPermissionsManuallyAccepted = true;
+ mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
}
- mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
} else {
destroyInternal();
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "User rejected permissions", null);
@@ -1120,7 +1355,9 @@
mCallback.onSessionActiveChanged(this, true);
}
+ boolean wasPrepared;
synchronized (mLock) {
+ wasPrepared = mPrepared;
if (!mPrepared) {
if (stageDir != null) {
prepareStageDir(stageDir);
@@ -1141,35 +1378,63 @@
}
mPrepared = true;
- mCallback.onSessionPrepared(this);
}
}
+
+ if (!wasPrepared) {
+ mCallback.onSessionPrepared(this);
+ }
}
@Override
public void close() {
- if (mActiveCount.decrementAndGet() == 0) {
+ closeInternal(true);
+ }
+
+ private void closeInternal(boolean checkCaller) {
+ int activeCount;
+ synchronized (mLock) {
+ if (checkCaller) {
+ assertCallerIsOwnerOrRootLocked();
+ }
+
+ activeCount = mActiveCount.decrementAndGet();
+ }
+
+ if (activeCount == 0) {
mCallback.onSessionActiveChanged(this, false);
}
}
@Override
public void abandon() {
- if (mRelinquished) {
- Slog.d(TAG, "Ignoring abandon after commit relinquished control");
- return;
+ synchronized (mLock) {
+ assertCallerIsOwnerOrRootLocked();
+
+ if (mRelinquished) {
+ Slog.d(TAG, "Ignoring abandon after commit relinquished control");
+ return;
+ }
+ destroyInternal();
}
- destroyInternal();
+
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
}
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
- mFinalStatus = returnCode;
- mFinalMessage = msg;
+ IPackageInstallObserver2 observer;
+ String packageName;
+ synchronized (mLock) {
+ mFinalStatus = returnCode;
+ mFinalMessage = msg;
- if (mRemoteObserver != null) {
+ observer = mRemoteObserver;
+ packageName = mPackageName;
+ }
+
+ if (observer != null) {
try {
- mRemoteObserver.onPackageInstalled(mPackageName, returnCode, msg, extras);
+ observer.onPackageInstalled(packageName, returnCode, msg, extras);
} catch (RemoteException ignored) {
}
}
@@ -1220,8 +1485,9 @@
pw.increaseIndent();
pw.printPair("userId", userId);
- pw.printPair("installerPackageName", installerPackageName);
- pw.printPair("installerUid", installerUid);
+ pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid);
+ pw.printPair("mInstallerPackageName", mInstallerPackageName);
+ pw.printPair("mInstallerUid", mInstallerUid);
pw.printPair("createdMillis", createdMillis);
pw.printPair("stageDir", stageDir);
pw.printPair("stageCid", stageCid);
@@ -1232,7 +1498,7 @@
pw.printPair("mClientProgress", mClientProgress);
pw.printPair("mProgress", mProgress);
pw.printPair("mSealed", mSealed);
- pw.printPair("mPermissionsAccepted", mPermissionsAccepted);
+ pw.printPair("mPermissionsManuallyAccepted", mPermissionsManuallyAccepted);
pw.printPair("mRelinquished", mRelinquished);
pw.printPair("mDestroyed", mDestroyed);
pw.printPair("mFds", mFds.size());
@@ -1243,4 +1509,170 @@
pw.decreaseIndent();
}
+
+ private static void writeGrantedRuntimePermissionsLocked(XmlSerializer out,
+ String[] grantedRuntimePermissions) throws IOException {
+ if (grantedRuntimePermissions != null) {
+ for (String permission : grantedRuntimePermissions) {
+ out.startTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
+ writeStringAttribute(out, ATTR_NAME, permission);
+ out.endTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
+ }
+ }
+ }
+
+ private static File buildAppIconFile(int sessionId, @NonNull File sessionsDir) {
+ return new File(sessionsDir, "app_icon." + sessionId + ".png");
+ }
+
+ /**
+ * Write this session to a {@link XmlSerializer}.
+ *
+ * @param out Where to write the session to
+ * @param sessionsDir The directory containing the sessions
+ */
+ void write(@NonNull XmlSerializer out, @NonNull File sessionsDir) throws IOException {
+ synchronized (mLock) {
+ out.startTag(null, TAG_SESSION);
+
+ writeIntAttribute(out, ATTR_SESSION_ID, sessionId);
+ writeIntAttribute(out, ATTR_USER_ID, userId);
+ writeStringAttribute(out, ATTR_INSTALLER_PACKAGE_NAME,
+ mInstallerPackageName);
+ writeIntAttribute(out, ATTR_INSTALLER_UID, mInstallerUid);
+ writeLongAttribute(out, ATTR_CREATED_MILLIS, createdMillis);
+ if (stageDir != null) {
+ writeStringAttribute(out, ATTR_SESSION_STAGE_DIR,
+ stageDir.getAbsolutePath());
+ }
+ if (stageCid != null) {
+ writeStringAttribute(out, ATTR_SESSION_STAGE_CID, stageCid);
+ }
+ writeBooleanAttribute(out, ATTR_PREPARED, isPrepared());
+ writeBooleanAttribute(out, ATTR_SEALED, isSealed());
+
+ writeIntAttribute(out, ATTR_MODE, params.mode);
+ writeIntAttribute(out, ATTR_INSTALL_FLAGS, params.installFlags);
+ writeIntAttribute(out, ATTR_INSTALL_LOCATION, params.installLocation);
+ writeLongAttribute(out, ATTR_SIZE_BYTES, params.sizeBytes);
+ writeStringAttribute(out, ATTR_APP_PACKAGE_NAME, params.appPackageName);
+ writeStringAttribute(out, ATTR_APP_LABEL, params.appLabel);
+ writeUriAttribute(out, ATTR_ORIGINATING_URI, params.originatingUri);
+ writeIntAttribute(out, ATTR_ORIGINATING_UID, params.originatingUid);
+ writeUriAttribute(out, ATTR_REFERRER_URI, params.referrerUri);
+ writeStringAttribute(out, ATTR_ABI_OVERRIDE, params.abiOverride);
+ writeStringAttribute(out, ATTR_VOLUME_UUID, params.volumeUuid);
+ writeIntAttribute(out, ATTR_INSTALL_REASON, params.installReason);
+
+ // Persist app icon if changed since last written
+ File appIconFile = buildAppIconFile(sessionId, sessionsDir);
+ if (params.appIcon == null && appIconFile.exists()) {
+ appIconFile.delete();
+ } else if (params.appIcon != null
+ && appIconFile.lastModified() != params.appIconLastModified) {
+ if (LOGD) Slog.w(TAG, "Writing changed icon " + appIconFile);
+ FileOutputStream os = null;
+ try {
+ os = new FileOutputStream(appIconFile);
+ params.appIcon.compress(Bitmap.CompressFormat.PNG, 90, os);
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to write icon " + appIconFile + ": " + e.getMessage());
+ } finally {
+ IoUtils.closeQuietly(os);
+ }
+
+ params.appIconLastModified = appIconFile.lastModified();
+ }
+
+ writeGrantedRuntimePermissionsLocked(out, params.grantedRuntimePermissions);
+ }
+
+ out.endTag(null, TAG_SESSION);
+ }
+
+ private static String[] readGrantedRuntimePermissions(XmlPullParser in)
+ throws IOException, XmlPullParserException {
+ List<String> permissions = null;
+
+ final int outerDepth = in.getDepth();
+ int type;
+ while ((type = in.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || in.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ if (TAG_GRANTED_RUNTIME_PERMISSION.equals(in.getName())) {
+ String permission = readStringAttribute(in, ATTR_NAME);
+ if (permissions == null) {
+ permissions = new ArrayList<>();
+ }
+ permissions.add(permission);
+ }
+ }
+
+ if (permissions == null) {
+ return null;
+ }
+
+ String[] permissionsArray = new String[permissions.size()];
+ permissions.toArray(permissionsArray);
+ return permissionsArray;
+ }
+
+ /**
+ * Read new session from a {@link XmlPullParser xml description} and create it.
+ *
+ * @param in The source of the description
+ * @param callback Callback the session uses to notify about changes of it's state
+ * @param context Context to be used by the session
+ * @param pm PackageManager to use by the session
+ * @param installerThread Thread to be used for callbacks of this session
+ * @param sessionsDir The directory the sessions are stored in
+ *
+ * @return The newly created session
+ */
+ public static PackageInstallerSession readFromXml(@NonNull XmlPullParser in,
+ @NonNull PackageInstallerService.InternalCallback callback, @NonNull Context context,
+ @NonNull PackageManagerService pm, Looper installerThread, @NonNull File sessionsDir)
+ throws IOException, XmlPullParserException {
+ final int sessionId = readIntAttribute(in, ATTR_SESSION_ID);
+ final int userId = readIntAttribute(in, ATTR_USER_ID);
+ final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
+ final int installerUid = readIntAttribute(in, ATTR_INSTALLER_UID, pm.getPackageUid(
+ installerPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId));
+ final long createdMillis = readLongAttribute(in, ATTR_CREATED_MILLIS);
+ final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR);
+ final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null;
+ final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID);
+ final boolean prepared = readBooleanAttribute(in, ATTR_PREPARED, true);
+ final boolean sealed = readBooleanAttribute(in, ATTR_SEALED);
+
+ final SessionParams params = new SessionParams(
+ SessionParams.MODE_INVALID);
+ params.mode = readIntAttribute(in, ATTR_MODE);
+ params.installFlags = readIntAttribute(in, ATTR_INSTALL_FLAGS);
+ params.installLocation = readIntAttribute(in, ATTR_INSTALL_LOCATION);
+ params.sizeBytes = readLongAttribute(in, ATTR_SIZE_BYTES);
+ params.appPackageName = readStringAttribute(in, ATTR_APP_PACKAGE_NAME);
+ params.appIcon = readBitmapAttribute(in, ATTR_APP_ICON);
+ params.appLabel = readStringAttribute(in, ATTR_APP_LABEL);
+ params.originatingUri = readUriAttribute(in, ATTR_ORIGINATING_URI);
+ params.originatingUid =
+ readIntAttribute(in, ATTR_ORIGINATING_UID, SessionParams.UID_UNKNOWN);
+ params.referrerUri = readUriAttribute(in, ATTR_REFERRER_URI);
+ params.abiOverride = readStringAttribute(in, ATTR_ABI_OVERRIDE);
+ params.volumeUuid = readStringAttribute(in, ATTR_VOLUME_UUID);
+ params.grantedRuntimePermissions = readGrantedRuntimePermissions(in);
+ params.installReason = readIntAttribute(in, ATTR_INSTALL_REASON);
+
+ final File appIconFile = buildAppIconFile(sessionId, sessionsDir);
+ if (appIconFile.exists()) {
+ params.appIcon = BitmapFactory.decodeFile(appIconFile.getAbsolutePath());
+ params.appIconLastModified = appIconFile.lastModified();
+ }
+
+ return new PackageInstallerSession(callback, context, pm,
+ installerThread, sessionId, userId, installerPackageName, installerUid,
+ params, createdMillis, stageDir, stageCid, prepared, sealed);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index baa2856..99261ad 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -143,6 +143,7 @@
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
+import android.content.pm.IPackageManagerNative;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstantAppInfo;
@@ -448,6 +449,7 @@
static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
static final int SCAN_AS_INSTANT_APP = 1<<17;
static final int SCAN_AS_FULL_APP = 1<<18;
+ static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
/** Should not be with the scan flags */
static final int FLAGS_REMOVE_CHATTY = 1<<31;
@@ -2304,6 +2306,8 @@
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
+ final PackageManagerNative pmn = m.new PackageManagerNative();
+ ServiceManager.addService("package_native", pmn);
return m;
}
@@ -2722,14 +2726,17 @@
//delete tmp files
deleteTempPackageFiles();
+ final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
+
// Remove any shared userIDs that have no associated packages
mSettings.pruneSharedUsersLPw();
final long systemScanTime = SystemClock.uptimeMillis() - startTime;
final int systemPackagesCount = mPackages.size();
Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
+ " ms, packageCount: " + systemPackagesCount
- + " ms, timePerPackage: "
- + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount));
+ + " , timePerPackage: "
+ + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
+ + " , cached: " + cachedSystemApps);
if (mIsUpgrade && systemPackagesCount > 0) {
MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
((int) systemScanTime) / systemPackagesCount);
@@ -2820,12 +2827,16 @@
// This must be done last to ensure all stubs are replaced or disabled.
decompressSystemApplications(stubSystemApps, scanFlags);
+ final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
+ - cachedSystemApps;
+
final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
final int dataPackagesCount = mPackages.size() - systemPackagesCount;
Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
+ " ms, packageCount: " + dataPackagesCount
- + " ms, timePerPackage: "
- + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount));
+ + " , timePerPackage: "
+ + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
+ + " , cached: " + cachedNonSystemApps);
if (mIsUpgrade && dataPackagesCount > 0) {
MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
((int) dataScanTime) / dataPackagesCount);
@@ -3347,7 +3358,7 @@
final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.USER_SYSTEM);
+ UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
if (matches.size() == 1) {
return matches.get(0).getComponentInfo().packageName;
} else if (matches.size() == 0) {
@@ -3407,7 +3418,7 @@
final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.USER_SYSTEM);
+ UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
ResolveInfo best = null;
final int N = matches.size();
for (int i = 0; i < N; i++) {
@@ -4223,20 +4234,69 @@
}
@Override
- public PermissionInfo getPermissionInfo(String name, int flags) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return null;
}
// reader
synchronized (mPackages) {
final BasePermission p = mSettings.mPermissions.get(name);
- if (p != null) {
- return generatePermissionInfo(p, flags);
+ if (p == null) {
+ return null;
}
- return null;
+ // If the caller is an app that targets pre 26 SDK drop protection flags.
+ final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
+ if (permissionInfo != null) {
+ permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
+ permissionInfo.protectionLevel, packageName, callingUid);
+ }
+ return permissionInfo;
}
}
+ private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
+ String packageName, int uid) {
+ // Signature permission flags area always reported
+ final int protectionLevelMasked = protectionLevel
+ & (PermissionInfo.PROTECTION_NORMAL
+ | PermissionInfo.PROTECTION_DANGEROUS
+ | PermissionInfo.PROTECTION_SIGNATURE);
+ if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
+ return protectionLevel;
+ }
+
+ // System sees all flags.
+ final int appId = UserHandle.getAppId(uid);
+ if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
+ || appId == Process.SHELL_UID) {
+ return protectionLevel;
+ }
+
+ // Normalize package name to handle renamed packages and static libs
+ packageName = resolveInternalPackageNameLPr(packageName,
+ PackageManager.VERSION_CODE_HIGHEST);
+
+ // Apps that target O see flags for all protection levels.
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
+ return protectionLevel;
+ }
+ if (ps.appId != appId) {
+ return protectionLevel;
+ }
+
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ return protectionLevel;
+ }
+ if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ return protectionLevelMasked;
+ }
+
+ return protectionLevel;
+ }
+
@Override
public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
int flags) {
@@ -6364,8 +6424,40 @@
}
return ps.name;
}
+ return null;
}
- return null;
+ }
+
+ @Override
+ public String[] getNamesForUids(int[] uids) {
+ if (uids == null || uids.length == 0) {
+ return null;
+ }
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
+ return null;
+ }
+ final String[] names = new String[uids.length];
+ synchronized (mPackages) {
+ for (int i = uids.length - 1; i >= 0; i--) {
+ final int uid = uids[i];
+ Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
+ if (obj instanceof SharedUserSetting) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ names[i] = "shared:" + sus.name;
+ } else if (obj instanceof PackageSetting) {
+ final PackageSetting ps = (PackageSetting) obj;
+ if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ names[i] = null;
+ } else {
+ names[i] = ps.name;
+ }
+ } else {
+ names[i] = null;
+ }
+ }
+ }
+ return names;
}
@Override
@@ -6494,7 +6586,7 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
- flags, callingUid, userId, resolveForStart);
+ flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
@@ -7039,12 +7131,13 @@
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
return queryIntentActivitiesInternal(
- intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
+ intent, resolvedType, flags, Binder.getCallingUid(), userId,
+ false /*resolveForStart*/, true /*allowDynamicSplits*/);
}
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int filterCallingUid, int userId,
- boolean resolveForStart) {
+ boolean resolveForStart, boolean allowDynamicSplits) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
@@ -7101,7 +7194,8 @@
list.add(ri);
}
}
- return applyPostResolutionFilter(list, instantAppPkgName);
+ return applyPostResolutionFilter(
+ list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
}
// reader
@@ -7120,7 +7214,8 @@
List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
xpResult.add(xpResolveInfo);
return applyPostResolutionFilter(
- filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
+ filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
+ allowDynamicSplits, filterCallingUid, userId);
}
// Check for results in the current profile.
@@ -7159,13 +7254,15 @@
// And we are not going to add emphemeral app, so we can return the
// result straight away.
result.add(xpDomainInfo.resolveInfo);
- return applyPostResolutionFilter(result, instantAppPkgName);
+ return applyPostResolutionFilter(result, instantAppPkgName,
+ allowDynamicSplits, filterCallingUid, userId);
}
} else if (result.size() <= 1 && !addEphemeral) {
// No result in parent user and <= 1 result in current profile, and we
// are not going to add emphemeral app, so we can return the result without
// further processing.
- return applyPostResolutionFilter(result, instantAppPkgName);
+ return applyPostResolutionFilter(result, instantAppPkgName,
+ allowDynamicSplits, filterCallingUid, userId);
}
// We have more than one candidate (combining results from current and parent
// profile), so we need filtering and sorting.
@@ -7200,7 +7297,8 @@
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
}
- return applyPostResolutionFilter(result, instantAppPkgName);
+ return applyPostResolutionFilter(
+ result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
}
private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
@@ -7266,7 +7364,8 @@
// the instant application, we'll do the right thing.
final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
auxiliaryResponse = new AuxiliaryResolveInfo(
- ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
+ ai.packageName, null /*splitName*/, null /*failureActivity*/,
+ ai.versionCode, null /*failureIntent*/);
}
}
if (auxiliaryResponse != null) {
@@ -7402,13 +7501,12 @@
* @return A filtered list of resolved activities.
*/
private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
- String ephemeralPkgName) {
+ String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
for (int i = resolveInfos.size() - 1; i >= 0; i--) {
final ResolveInfo info = resolveInfos.get(i);
- // TODO: When adding on-demand split support for non-instant apps, remove this check
- // and always apply post filtering
// allow activities that are defined in the provided package
- if (info.activityInfo.splitName != null
+ if (allowDynamicSplits
+ && info.activityInfo.splitName != null
&& !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
info.activityInfo.splitName)) {
// requested activity is defined in a split that hasn't been installed yet.
@@ -7417,9 +7515,13 @@
Slog.v(TAG, "Adding installer to the ResolveInfo list");
}
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+ final ComponentName installFailureActivity = findInstallFailureActivity(
+ info.activityInfo.packageName, filterCallingUid, userId);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.activityInfo.packageName, info.activityInfo.splitName,
- info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
+ installFailureActivity,
+ info.activityInfo.applicationInfo.versionCode,
+ null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7450,6 +7552,34 @@
}
/**
+ * Returns the activity component that can handle install failures.
+ * <p>By default, the instant application installer handles failures. However, an
+ * application may want to handle failures on its own. Applications do this by
+ * creating an activity with an intent filter that handles the action
+ * {@link Intent#ACTION_INSTALL_FAILURE}.
+ */
+ private @Nullable ComponentName findInstallFailureActivity(
+ String packageName, int filterCallingUid, int userId) {
+ final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
+ failureActivityIntent.setPackage(packageName);
+ // IMPORTANT: disallow dynamic splits to avoid an infinite loop
+ final List<ResolveInfo> result = queryIntentActivitiesInternal(
+ failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
+ false /*resolveForStart*/, false /*allowDynamicSplits*/);
+ final int NR = result.size();
+ if (NR > 0) {
+ for (int i = 0; i < NR; i++) {
+ final ResolveInfo info = result.get(i);
+ if (info.activityInfo.splitName != null) {
+ continue;
+ }
+ return new ComponentName(packageName, info.activityInfo.name);
+ }
+ }
+ return null;
+ }
+
+ /**
* @param resolveInfos list of resolve infos in descending priority order
* @return if the list contains a resolve info with non-negative priority
*/
@@ -7936,13 +8066,17 @@
public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, int flags, int userId) {
return new ParceledListSlice<>(
- queryIntentReceiversInternal(intent, resolvedType, flags, userId));
+ queryIntentReceiversInternal(intent, resolvedType, flags, userId,
+ false /*allowDynamicSplits*/));
}
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
- String resolvedType, int flags, int userId) {
+ String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
+ false /*requireFullPermission*/, false /*checkShell*/,
+ "query intent receivers");
final String instantAppPkgName = getInstantAppPackageName(callingUid);
flags = updateFlagsForResolve(flags, userId, intent, callingUid,
false /*includeInstantApps*/);
@@ -7993,7 +8127,8 @@
list.add(ri);
}
}
- return applyPostResolutionFilter(list, instantAppPkgName);
+ return applyPostResolutionFilter(
+ list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
}
// reader
@@ -8002,13 +8137,15 @@
if (pkgName == null) {
final List<ResolveInfo> result =
mReceivers.queryIntent(intent, resolvedType, flags, userId);
- return applyPostResolutionFilter(result, instantAppPkgName);
+ return applyPostResolutionFilter(
+ result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
intent, resolvedType, flags, pkg.receivers, userId);
- return applyPostResolutionFilter(result, instantAppPkgName);
+ return applyPostResolutionFilter(
+ result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
}
return Collections.emptyList();
}
@@ -8049,6 +8186,9 @@
String resolvedType, int flags, int userId, int callingUid,
boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
+ enforceCrossUserPermission(callingUid, userId,
+ false /*requireFullPermission*/, false /*checkShell*/,
+ "query intent receivers");
final String instantAppPkgName = getInstantAppPackageName(callingUid);
flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
ComponentName comp = intent.getComponent();
@@ -8114,8 +8254,6 @@
private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
String instantAppPkgName) {
- // TODO: When adding on-demand split support for non-instant apps, remove this check
- // and always apply post filtering
if (instantAppPkgName == null) {
return resolveInfos;
}
@@ -8135,7 +8273,8 @@
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.serviceInfo.packageName, info.serviceInfo.splitName,
- info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
+ null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
+ null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -8235,8 +8374,6 @@
private List<ResolveInfo> applyPostContentProviderResolutionFilter(
List<ResolveInfo> resolveInfos, String instantAppPkgName) {
- // TODO: When adding on-demand split support for non-instant applications, remove
- // this check and always apply post filtering
if (instantAppPkgName == null) {
return resolveInfos;
}
@@ -8256,7 +8393,8 @@
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.providerInfo.packageName, info.providerInfo.splitName,
- info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
+ null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
+ null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -8476,8 +8614,10 @@
if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
return null;
}
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
- "getEphemeralApplications");
+ if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+ "getEphemeralApplications");
+ }
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
"getEphemeralApplications");
@@ -8562,9 +8702,10 @@
return null;
}
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
- "getInstantAppIcon");
-
+ if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
+ "getInstantAppIcon");
+ }
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
"getInstantAppIcon");
@@ -9304,6 +9445,9 @@
if (ps != null && ps.getInstantApp(userId)) {
scanFlags |= SCAN_AS_INSTANT_APP;
}
+ if (ps != null && ps.getVirtulalPreload(userId)) {
+ scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
+ }
// Note that we invoke the following method only if we are about to unpack an application
PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
@@ -9628,7 +9772,8 @@
}
@Override
- public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
+ public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
+ List<String> classPaths, String loaderIsa) {
int userId = UserHandle.getCallingUserId();
ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
if (ai == null) {
@@ -9636,7 +9781,7 @@
+ loadingPackageName + ", user=" + userId);
return;
}
- mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
+ mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
}
@Override
@@ -9786,17 +9931,19 @@
Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
if (!deps.isEmpty()) {
+ DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
+ options.getCompilerFilter(), options.getSplitName(),
+ options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
for (PackageParser.Package depPackage : deps) {
// TODO: Analyze and investigate if we (should) profile libraries.
pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
getOrCreateCompilerPackageStats(depPackage),
- true /* isUsedByOtherApps */,
- options);
+ mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
}
}
return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
getOrCreateCompilerPackageStats(p),
- mDexManager.isUsedByOtherApps(p.packageName), options);
+ mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
}
/**
@@ -9922,6 +10069,7 @@
public void shutdown() {
mPackageUsage.writeNow(mPackages);
mCompilerStats.writeNow();
+ mDexManager.writePackageDexUsageNow();
}
@Override
@@ -10552,15 +10700,17 @@
final String parentPackageName = (pkg.parentPackage != null)
? pkg.parentPackage.packageName : null;
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
+ final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
// REMOVE SharedUserSetting from method; update in a separate call
pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
- true /*allowInstall*/, instantApp, parentPackageName,
- pkg.getChildPackageNames(), UserManagerService.getInstance(),
- usesStaticLibraries, pkg.usesStaticLibrariesVersions);
+ true /*allowInstall*/, instantApp, virtualPreload,
+ parentPackageName, pkg.getChildPackageNames(),
+ UserManagerService.getInstance(), usesStaticLibraries,
+ pkg.usesStaticLibrariesVersions);
// SIDE EFFECTS; updates system state; move elsewhere
if (origPackage != null) {
mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
@@ -15273,6 +15423,11 @@
@Override
public int getIntentVerificationStatus(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
+ if (UserHandle.getUserId(callingUid) != userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "getIntentVerificationStatus" + userId);
+ }
if (getInstantAppPackageName(callingUid) != null) {
return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
@@ -15356,6 +15511,10 @@
public boolean setDefaultBrowserPackageName(String packageName, int userId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
synchronized (mPackages) {
boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
@@ -15369,6 +15528,10 @@
@Override
public String getDefaultBrowserPackageName(int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return null;
}
@@ -16101,7 +16264,8 @@
// Query all live verifiers based on current user state
final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
- PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
+ PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
+ false /*allowDynamicSplits*/);
if (DEBUG_VERIFY) {
Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
@@ -18063,6 +18227,8 @@
final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
+ final boolean virtualPreload =
+ ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
boolean replace = false;
int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
if (args.move != null) {
@@ -18078,6 +18244,9 @@
if (fullApp) {
scanFlags |= SCAN_AS_FULL_APP;
}
+ if (virtualPreload) {
+ scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
+ }
// Result object to be returned
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
@@ -18457,7 +18626,7 @@
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
null /* instructionSets */,
getOrCreateCompilerPackageStats(pkg),
- mDexManager.isUsedByOtherApps(pkg.packageName),
+ mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
dexoptOptions);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -19868,6 +20037,7 @@
false /*hidden*/,
false /*suspended*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
@@ -22755,7 +22925,8 @@
for (PackageParser.Package pkg : packages) {
ipw.println("[" + pkg.packageName + "]");
ipw.increaseIndent();
- mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
+ mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
+ mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
ipw.decreaseIndent();
}
}
@@ -24686,6 +24857,20 @@
}
}
+ private class PackageManagerNative extends IPackageManagerNative.Stub {
+ @Override
+ public String[] getNamesForUids(int[] uids) throws RemoteException {
+ final String[] results = PackageManagerService.this.getNamesForUids(uids);
+ // massage results so they can be parsed by the native binder
+ for (int i = results.length - 1; i >= 0; --i) {
+ if (results[i] == null) {
+ results[i] = "";
+ }
+ }
+ return results;
+ }
+ }
+
private class PackageManagerInternalImpl extends PackageManagerInternal {
@Override
public void setLocationPackagesProvider(PackagesProvider provider) {
@@ -24834,7 +25019,7 @@
final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
return PackageManagerService.this
.queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
- userId, false /*resolveForStart*/);
+ userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
}
@Override
@@ -25280,8 +25465,8 @@
if (ps == null) {
continue;
}
- PackageDexUsage.PackageUseInfo packageUseInfo = getDexManager().getPackageUseInfo(
- pkg.packageName);
+ PackageDexUsage.PackageUseInfo packageUseInfo =
+ getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
if (PackageManagerServiceUtils
.isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
downgradeTimeThresholdMillis, packageUseInfo,
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index a7031c9..25fef0a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -25,7 +25,6 @@
import android.annotation.NonNull;
import android.app.AppGlobals;
import android.content.Intent;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.content.pm.ResolveInfo;
import android.os.Build;
@@ -137,9 +136,11 @@
sortTemp, packageManagerService);
// Give priority to apps used by other apps.
+ DexManager dexManager = packageManagerService.getDexManager();
applyPackageFilter((pkg) ->
- packageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), result,
- remainingPkgs, sortTemp, packageManagerService);
+ dexManager.getPackageUseInfoOrDefault(pkg.packageName)
+ .isAnyCodePathUsedByOtherApps(),
+ result, remainingPkgs, sortTemp, packageManagerService);
// Filter out packages that aren't recently used, add all remaining apps.
// TODO: add a property to control this?
@@ -209,12 +210,10 @@
// If the app was active in background during the threshold period and was used
// by other packages.
- // If packageUseInfo is null, it can be said that the package was not used by other
- // packages.
boolean isActiveInBackgroundAndUsedByOtherPackages = ((currentTimeInMillis
- latestPackageUseTimeInMillis)
< thresholdTimeinMillis)
- && (packageUseInfo != null && packageUseInfo.isUsedByOtherApps());
+ && packageUseInfo.isAnyCodePathUsedByOtherApps();
return !isActiveInBackgroundAndUsedByOtherPackages;
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index f685127..d3ca1fd 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -420,11 +420,19 @@
modifyUserState(userId).instantApp = instantApp;
}
+ boolean getVirtulalPreload(int userId) {
+ return readUserState(userId).virtualPreload;
+ }
+
+ void setVirtualPreload(boolean virtualPreload, int userId) {
+ modifyUserState(userId).virtualPreload = virtualPreload;
+ }
+
void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
- String lastDisableAppCaller, ArraySet<String> enabledComponents,
- ArraySet<String> disabledComponents, int domainVerifState,
- int linkGeneration, int installReason) {
+ boolean virtualPreload, String lastDisableAppCaller,
+ ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
+ int domainVerifState, int linkGeneration, int installReason) {
PackageUserState state = modifyUserState(userId);
state.ceDataInode = ceDataInode;
state.enabled = enabled;
@@ -440,6 +448,7 @@
state.appLinkGeneration = linkGeneration;
state.installReason = installReason;
state.instantApp = instantApp;
+ state.virtualPreload = virtualPreload;
}
ArraySet<String> getEnabledComponents(int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 45d0c58..d99408f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -226,6 +226,7 @@
private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
private static final String ATTR_INSTALL_REASON = "install-reason";
private static final String ATTR_INSTANT_APP = "instant-app";
+ private static final String ATTR_VIRTUAL_PRELOAD = "virtual-preload";
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_FINGERPRINT = "fingerprint";
@@ -697,8 +698,9 @@
PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser,
File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi,
String secondaryCpuAbi, int versionCode, int pkgFlags, int pkgPrivateFlags,
- UserHandle installUser, boolean allowInstall, boolean instantApp, String parentPkgName,
- List<String> childPkgNames, UserManagerService userManager,
+ UserHandle installUser, boolean allowInstall, boolean instantApp,
+ boolean virtualPreload, String parentPkgName, List<String> childPkgNames,
+ UserManagerService userManager,
String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) {
final PackageSetting pkgSetting;
if (originalPkg != null) {
@@ -760,6 +762,7 @@
false /*hidden*/,
false /*suspended*/,
instantApp,
+ virtualPreload,
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
@@ -1693,6 +1696,7 @@
false /*hidden*/,
false /*suspended*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
@@ -1766,6 +1770,8 @@
ATTR_BLOCK_UNINSTALL, false);
final boolean instantApp = XmlUtils.readBooleanAttribute(parser,
ATTR_INSTANT_APP, false);
+ final boolean virtualPreload = XmlUtils.readBooleanAttribute(parser,
+ ATTR_VIRTUAL_PRELOAD, false);
final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
COMPONENT_ENABLED_STATE_DEFAULT);
final String enabledCaller = parser.getAttributeValue(null,
@@ -1805,8 +1811,8 @@
setBlockUninstallLPw(userId, name, true);
}
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
- hidden, suspended, instantApp, enabledCaller, enabledComponents,
- disabledComponents, verifState, linkGeneration,
+ hidden, suspended, instantApp, virtualPreload, enabledCaller,
+ enabledComponents, disabledComponents, verifState, linkGeneration,
installReason);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
@@ -2117,6 +2123,9 @@
if (ustate.instantApp) {
serializer.attribute(null, ATTR_INSTANT_APP, "true");
}
+ if (ustate.virtualPreload) {
+ serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true");
+ }
if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
serializer.attribute(null, ATTR_ENABLED,
Integer.toString(ustate.enabled));
@@ -4603,6 +4612,7 @@
pw.print(ps.getStopped(user.id) ? "S" : "s");
pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
pw.print(ps.getInstantApp(user.id) ? "IA" : "ia");
+ pw.print(ps.getVirtulalPreload(user.id) ? "VPI" : "vpi");
pw.print(",");
pw.print(ps.getEnabled(user.id));
String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
@@ -4858,6 +4868,8 @@
pw.print(ps.getEnabled(user.id));
pw.print(" instant=");
pw.println(ps.getInstantApp(user.id));
+ pw.print(" virtual=");
+ pw.println(ps.getVirtulalPreload(user.id));
String[] overlayPaths = ps.getOverlayPaths(user.id);
if (overlayPaths != null && overlayPaths.length > 0) {
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 3d2d483..6274754 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -36,6 +36,8 @@
import java.io.File;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
@@ -81,6 +83,19 @@
private static int DEX_SEARCH_FOUND_SPLIT = 2; // dex file is a split apk
private static int DEX_SEARCH_FOUND_SECONDARY = 3; // dex file is a secondary dex
+ /**
+ * We do not record packages that have no secondary dex files or that are not used by other
+ * apps. This is an optimization to reduce the amount of data that needs to be written to
+ * disk (apps will not usually be shared so this trims quite a bit the number we record).
+ *
+ * To make this behaviour transparent to the callers which need use information on packages,
+ * DexManager will return this DEFAULT instance from
+ * {@link DexManager#getPackageUseInfoOrDefault}. It has no data about secondary dex files and
+ * is marked as not being used by other apps. This reflects the intended behaviour when we don't
+ * find the package in the underlying data file.
+ */
+ private final static PackageUseInfo DEFAULT_USE_INFO = new PackageUseInfo();
+
public DexManager(IPackageManager pms, PackageDexOptimizer pdo,
Installer installer, Object installLock) {
mPackageCodeLocationsCache = new HashMap<>();
@@ -97,29 +112,55 @@
* return as fast as possible.
*
* @param loadingAppInfo the package performing the load
- * @param dexPaths the list of dex files being loaded
+ * @param classLoadersNames the names of the class loaders present in the loading chain. The
+ * list encodes the class loader chain in the natural order. The first class loader has
+ * the second one as its parent and so on. The dex files present in the class path of the
+ * first class loader will be recorded in the usage file.
+ * @param classPaths the class paths corresponding to the class loaders names from
+ * {@param classLoadersNames}. The the first element corresponds to the first class loader
+ * and so on. A classpath is represented as a list of dex files separated by
+ * {@code File.pathSeparator}.
+ * The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the app loading the dex files
* @param loaderUserId the user id which runs the code loading the dex files
*/
- public void notifyDexLoad(ApplicationInfo loadingAppInfo, List<String> dexPaths,
- String loaderIsa, int loaderUserId) {
+ public void notifyDexLoad(ApplicationInfo loadingAppInfo, List<String> classLoadersNames,
+ List<String> classPaths, String loaderIsa, int loaderUserId) {
try {
- notifyDexLoadInternal(loadingAppInfo, dexPaths, loaderIsa, loaderUserId);
+ notifyDexLoadInternal(loadingAppInfo, classLoadersNames, classPaths, loaderIsa,
+ loaderUserId);
} catch (Exception e) {
Slog.w(TAG, "Exception while notifying dex load for package " +
loadingAppInfo.packageName, e);
}
}
- private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, List<String> dexPaths,
- String loaderIsa, int loaderUserId) {
+ private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
+ List<String> classLoaderNames, List<String> classPaths, String loaderIsa,
+ int loaderUserId) {
+ if (classLoaderNames.size() != classPaths.size()) {
+ Slog.wtf(TAG, "Bad call to noitfyDexLoad: args have different size");
+ return;
+ }
+ if (classLoaderNames.isEmpty()) {
+ Slog.wtf(TAG, "Bad call to notifyDexLoad: class loaders list is empty");
+ return;
+ }
if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
- Slog.w(TAG, "Loading dex files " + dexPaths + " in unsupported ISA: " +
+ Slog.w(TAG, "Loading dex files " + classPaths + " in unsupported ISA: " +
loaderIsa + "?");
return;
}
- for (String dexPath : dexPaths) {
+ // The classpath is represented as a list of dex files separated by File.pathSeparator.
+ String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator);
+
+ // Encode the class loader contexts for the dexPathsToRegister.
+ String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
+ classLoaderNames, classPaths);
+
+ int dexPathIndex = 0;
+ for (String dexPath : dexPathsToRegister) {
// Find the owning package name.
DexSearchResult searchResult = getDexPackage(loadingAppInfo, dexPath, loaderUserId);
@@ -147,24 +188,25 @@
// Record dex file usage. If the current usage is a new pattern (e.g. new secondary,
// or UsedBytOtherApps), record will return true and we trigger an async write
// to disk to make sure we don't loose the data in case of a reboot.
+
+ // A null classLoaderContexts means that there are unsupported class loaders in the
+ // chain.
+ String classLoaderContext = classLoaderContexts == null
+ ? PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT
+ : classLoaderContexts[dexPathIndex];
if (mPackageDexUsage.record(searchResult.mOwningPackageName,
dexPath, loaderUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
- loadingAppInfo.packageName)) {
+ loadingAppInfo.packageName, classLoaderContext)) {
mPackageDexUsage.maybeWriteAsync();
}
} else {
- // This can happen in a few situations:
- // - bogus dex loads
- // - recent installs/uninstalls that we didn't detect.
- // - new installed splits
// If we can't find the owner of the dex we simply do not track it. The impact is
// that the dex file will not be considered for offline optimizations.
- // TODO(calin): add hooks for move/uninstall notifications to
- // capture package moves or obsolete packages.
if (DEBUG) {
Slog.i(TAG, "Could not find owning package for dex file: " + dexPath);
}
}
+ dexPathIndex++;
}
}
@@ -270,6 +312,8 @@
private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) {
Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
+ Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+
// Cache the code locations for the installed packages. This allows for
// faster lookups (no locks) when finding what package owns the dex file.
for (Map.Entry<Integer, List<PackageInfo>> entry : existingPackages.entrySet()) {
@@ -279,25 +323,53 @@
// Cache the code locations.
cachePackageInfo(pi, userId);
- // Cache a map from package name to the set of user ids who installed the package.
+ // Cache two maps:
+ // - from package name to the set of user ids who installed the package.
+ // - from package name to the set of code paths.
// We will use it to sync the data and remove obsolete entries from
// mPackageDexUsage.
Set<Integer> users = putIfAbsent(
packageToUsersMap, pi.packageName, new HashSet<>());
users.add(userId);
+
+ Set<String> codePaths = putIfAbsent(
+ packageToCodePaths, pi.packageName, new HashSet<>());
+ codePaths.add(pi.applicationInfo.sourceDir);
+ if (pi.applicationInfo.splitSourceDirs != null) {
+ Collections.addAll(codePaths, pi.applicationInfo.splitSourceDirs);
+ }
}
}
mPackageDexUsage.read();
- mPackageDexUsage.syncData(packageToUsersMap);
+ mPackageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
}
/**
* Get the package dex usage for the given package name.
- * @return the package data or null if there is no data available for this package.
+ * If there is no usage info the method will return a default {@code PackageUseInfo} with
+ * no data about secondary dex files and marked as not being used by other apps.
+ *
+ * Note that no use info means the package was not used or it was used but not by other apps.
+ * Also, note that right now we might prune packages which are not used by other apps.
+ * TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
+ * to access the package use.
*/
- public PackageUseInfo getPackageUseInfo(String packageName) {
- return mPackageDexUsage.getPackageUseInfo(packageName);
+ public PackageUseInfo getPackageUseInfoOrDefault(String packageName) {
+ PackageUseInfo useInfo = mPackageDexUsage.getPackageUseInfo(packageName);
+ return useInfo == null ? DEFAULT_USE_INFO : useInfo;
+ }
+
+ /**
+ * Return whether or not the manager has usage information on the give package.
+ *
+ * Note that no use info means the package was not used or it was used but not by other apps.
+ * Also, note that right now we might prune packages which are not used by other apps.
+ * TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
+ * to access the package use.
+ */
+ /*package*/ boolean hasInfoOnPackage(String packageName) {
+ return mPackageDexUsage.getPackageUseInfo(packageName) != null;
}
/**
@@ -316,7 +388,7 @@
? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
: mPackageDexOptimizer;
String packageName = options.getPackageName();
- PackageUseInfo useInfo = getPackageUseInfo(packageName);
+ PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName);
if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
if (DEBUG) {
Slog.d(TAG, "No secondary dex use for package:" + packageName);
@@ -328,10 +400,8 @@
for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
String dexPath = entry.getKey();
DexUseInfo dexUseInfo = entry.getValue();
- if (options.isDexoptOnlySharedDex() && !dexUseInfo.isUsedByOtherApps()) {
- continue;
- }
- PackageInfo pkg = null;
+
+ PackageInfo pkg;
try {
pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
dexUseInfo.getOwnerUserId());
@@ -350,8 +420,7 @@
}
int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath,
- dexUseInfo.getLoaderIsas(), options.getCompilerFilter(),
- dexUseInfo.isUsedByOtherApps(), options.isDowngrade());
+ dexUseInfo, options);
success = success && (result != PackageDexOptimizer.DEX_OPT_FAILED);
}
return success;
@@ -363,7 +432,7 @@
* deleted, update the internal records and delete any generated oat files.
*/
public void reconcileSecondaryDexFiles(String packageName) {
- PackageUseInfo useInfo = getPackageUseInfo(packageName);
+ PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName);
if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
if (DEBUG) {
Slog.d(TAG, "No secondary dex use for package:" + packageName);
@@ -434,6 +503,8 @@
}
}
+ // TODO(calin): questionable API in the presence of class loaders context. Needs amends as the
+ // compilation happening here will use a pessimistic context.
public RegisterDexModuleResult registerDexModule(ApplicationInfo info, String dexPath,
boolean isUsedByOtherApps, int userId) {
// Find the owning package record.
@@ -452,12 +523,11 @@
// We found the package. Now record the usage for all declared ISAs.
boolean update = false;
- Set<String> isas = new HashSet<>();
for (String isa : getAppDexInstructionSets(info)) {
- isas.add(isa);
boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
dexPath, userId, isa, isUsedByOtherApps, /*primaryOrSplit*/ false,
- searchResult.mOwningPackageName);
+ searchResult.mOwningPackageName,
+ PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT);
update |= newUpdate;
}
if (update) {
@@ -467,8 +537,13 @@
// Try to optimize the package according to the install reason.
String compilerFilter = PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
PackageManagerService.REASON_INSTALL);
- int result = mPackageDexOptimizer.dexOptSecondaryDexPath(info, dexPath, isas,
- compilerFilter, isUsedByOtherApps, /* downgrade */ false);
+ DexUseInfo dexUseInfo = mPackageDexUsage.getPackageUseInfo(searchResult.mOwningPackageName)
+ .getDexUseInfoMap().get(dexPath);
+
+ DexoptOptions options = new DexoptOptions(info.packageName, compilerFilter, /*flags*/0);
+
+ int result = mPackageDexOptimizer.dexOptSecondaryDexPath(info, dexPath, dexUseInfo,
+ options);
// If we fail to optimize the package log an error but don't propagate the error
// back to the app. The app cannot do much about it and the background job
@@ -489,23 +564,6 @@
}
/**
- * Return true if the profiling data collected for the given app indicate
- * that the apps's APK has been loaded by another app.
- * Note that this returns false for all apps without any collected profiling data.
- */
- public boolean isUsedByOtherApps(String packageName) {
- PackageUseInfo useInfo = getPackageUseInfo(packageName);
- if (useInfo == null) {
- // No use info, means the package was not used or it was used but not by other apps.
- // Note that right now we might prune packages which are not used by other apps.
- // TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
- // to access the package use.
- return false;
- }
- return useInfo.isUsedByOtherApps();
- }
-
- /**
* Retrieves the package which owns the given dexPath.
*/
private DexSearchResult getDexPackage(
@@ -562,6 +620,13 @@
return existingValue == null ? newValue : existingValue;
}
+ /**
+ * Writes the in-memory package dex usage to disk right away.
+ */
+ public void writePackageDexUsageNow() {
+ mPackageDexUsage.writeNow();
+ }
+
public static class RegisterDexModuleResult {
public RegisterDexModuleResult() {
this(false, null);
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index f57cf5e..4fa47b5 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -50,6 +50,12 @@
// save disk space.
public static final int DEXOPT_DOWNGRADE = 1 << 5;
+ // When set, dexopt will compile the dex file as a shared library even if it is not actually
+ // used by other apps. This is used to force the compilation or shared libraries declared
+ // with in the manifest with ''uses-library' before we have a chance to detect they are
+ // actually shared at runtime.
+ public static final int DEXOPT_AS_SHARED_LIBRARY = 1 << 6;
+
// The name of package to optimize.
private final String mPackageName;
@@ -79,7 +85,8 @@
DEXOPT_BOOT_COMPLETE |
DEXOPT_ONLY_SECONDARY_DEX |
DEXOPT_ONLY_SHARED_DEX |
- DEXOPT_DOWNGRADE;
+ DEXOPT_DOWNGRADE |
+ DEXOPT_AS_SHARED_LIBRARY;
if ((flags & (~validityMask)) != 0) {
throw new IllegalArgumentException("Invalid flags : " + Integer.toHexString(flags));
}
@@ -122,7 +129,15 @@
return (mFlags & DEXOPT_DOWNGRADE) != 0;
}
+ public boolean isDexoptAsSharedLibrary() {
+ return (mFlags & DEXOPT_AS_SHARED_LIBRARY) != 0;
+ }
+
public String getSplitName() {
return mSplitName;
}
+
+ public int getFlags() {
+ return mFlags;
+ }
}
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index 18e91df..0196212 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -23,6 +23,8 @@
import com.android.internal.os.ClassLoaderFactory;
import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public final class DexoptUtils {
@@ -229,7 +231,76 @@
* dependencies {@see encodeClassLoader} separated by ';'.
*/
private static String encodeClassLoaderChain(String cl1, String cl2) {
- return cl1.isEmpty() ? cl2 : (cl1 + ";" + cl2);
+ if (cl1.isEmpty()) return cl2;
+ if (cl2.isEmpty()) return cl1;
+ return cl1 + ";" + cl2;
+ }
+
+ /**
+ * Compute the class loader context for the dex files present in the classpath of the first
+ * class loader from the given list (referred in the code as the {@code loadingClassLoader}).
+ * Each dex files gets its own class loader context in the returned array.
+ *
+ * Example:
+ * If classLoadersNames = {"dalvik.system.DelegateLastClassLoader",
+ * "dalvik.system.PathClassLoader"} and classPaths = {"foo.dex:bar.dex", "other.dex"}
+ * The output will be
+ * {"DLC[];PCL[other.dex]", "DLC[foo.dex];PCL[other.dex]"}
+ * with "DLC[];PCL[other.dex]" being the context for "foo.dex"
+ * and "DLC[foo.dex];PCL[other.dex]" the context for "bar.dex".
+ *
+ * If any of the class loaders names is unsupported the method will return null.
+ *
+ * The argument lists must be non empty and of the same size.
+ *
+ * @param classLoadersNames the names of the class loaders present in the loading chain. The
+ * list encodes the class loader chain in the natural order. The first class loader has
+ * the second one as its parent and so on.
+ * @param classPaths the class paths for the elements of {@param classLoadersNames}. The
+ * the first element corresponds to the first class loader and so on. A classpath is
+ * represented as a list of dex files separated by {@code File.pathSeparator}.
+ * The return context will be for the dex files found in the first class path.
+ */
+ /*package*/ static String[] processContextForDexLoad(List<String> classLoadersNames,
+ List<String> classPaths) {
+ if (classLoadersNames.size() != classPaths.size()) {
+ throw new IllegalArgumentException(
+ "The size of the class loader names and the dex paths do not match.");
+ }
+ if (classLoadersNames.isEmpty()) {
+ throw new IllegalArgumentException("Empty classLoadersNames");
+ }
+
+ // Compute the context for the parent class loaders.
+ String parentContext = "";
+ // We know that these lists are actually ArrayLists so getting the elements by index
+ // is fine (they come over binder). Even if something changes we expect the sizes to be
+ // very small and it shouldn't matter much.
+ for (int i = 1; i < classLoadersNames.size(); i++) {
+ if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) {
+ return null;
+ }
+ String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator));
+ parentContext = encodeClassLoaderChain(parentContext,
+ encodeClassLoader(classpath, classLoadersNames.get(i)));
+ }
+
+ // Now compute the class loader context for each dex file from the first classpath.
+ String loadingClassLoader = classLoadersNames.get(0);
+ if (!ClassLoaderFactory.isValidClassLoaderName(loadingClassLoader)) {
+ return null;
+ }
+ String[] loadedDexPaths = classPaths.get(0).split(File.pathSeparator);
+ String[] loadedDexPathsContext = new String[loadedDexPaths.length];
+ String currentLoadedDexPathClasspath = "";
+ for (int i = 0; i < loadedDexPaths.length; i++) {
+ String dexPath = loadedDexPaths[i];
+ String currentContext = encodeClassLoader(
+ currentLoadedDexPathClasspath, loadingClassLoader);
+ loadedDexPathsContext[i] = encodeClassLoaderChain(currentContext, parentContext);
+ currentLoadedDexPathClasspath = encodeClasspath(currentLoadedDexPathClasspath, dexPath);
+ }
+ return loadedDexPathsContext;
}
/**
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index f7dd174..a4a0a54 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -26,7 +26,6 @@
import com.android.server.pm.PackageManagerServiceUtils;
import java.io.BufferedReader;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
@@ -55,17 +54,38 @@
public class PackageDexUsage extends AbstractStatsBase<Void> {
private final static String TAG = "PackageDexUsage";
- // The last version update: add the list of packages that load the dex files.
- private final static int PACKAGE_DEX_USAGE_VERSION = 2;
- // We support VERSION 1 to ensure that the usage list remains valid cross OTAs.
+ // We support previous version to ensure that the usage list remains valid cross OTAs.
private final static int PACKAGE_DEX_USAGE_SUPPORTED_VERSION_1 = 1;
+ // Version 2 added:
+ // - the list of packages that load the dex files
+ // - class loader contexts for secondary dex files
+ // - usage for all code paths (including splits)
+ private final static int PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2 = 2;
+
+ private final static int PACKAGE_DEX_USAGE_VERSION = PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2;
private final static String PACKAGE_DEX_USAGE_VERSION_HEADER =
"PACKAGE_MANAGER__PACKAGE_DEX_USAGE__";
private final static String SPLIT_CHAR = ",";
+ private final static String CODE_PATH_LINE_CHAR = "+";
private final static String DEX_LINE_CHAR = "#";
private final static String LOADING_PACKAGE_CHAR = "@";
+
+ // One of the things we record about dex files is the class loader context that was used to
+ // load them. That should be stable but if it changes we don't keep track of variable contexts.
+ // Instead we put a special marker in the dex usage file in order to recognize the case and
+ // skip optimizations on that dex files.
+ /*package*/ static final String VARIABLE_CLASS_LOADER_CONTEXT =
+ "=VariableClassLoaderContext=";
+ // The marker used for unsupported class loader contexts.
+ /*package*/ static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
+ "=UnsupportedClassLoaderContext=";
+ // The markers used for unknown class loader contexts. This can happen if the dex file was
+ // recorded in a previous version and we didn't have a chance to update its usage.
+ /*package*/ static final String UNKNOWN_CLASS_LOADER_CONTEXT =
+ "=UnknownClassLoaderContext=";
+
// Map which structures the information we have on a package.
// Maps package name to package data (which stores info about UsedByOtherApps and
// secondary dex files.).
@@ -98,10 +118,14 @@
*/
public boolean record(String owningPackageName, String dexPath, int ownerUserId,
String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit,
- String loadingPackageName) {
+ String loadingPackageName, String classLoaderContext) {
if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
throw new IllegalArgumentException("loaderIsa " + loaderIsa + " is unsupported");
}
+ if (classLoaderContext == null) {
+ throw new IllegalArgumentException("Null classLoaderContext");
+ }
+
synchronized (mPackageUseInfoMap) {
PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(owningPackageName);
if (packageUseInfo == null) {
@@ -111,13 +135,13 @@
// If we have a primary or a split apk, set isUsedByOtherApps.
// We do not need to record the loaderIsa or the owner because we compile
// primaries for all users and all ISAs.
- packageUseInfo.mIsUsedByOtherApps = isUsedByOtherApps;
- maybeAddLoadingPackage(owningPackageName, loadingPackageName,
- packageUseInfo.mLoadingPackages);
+ packageUseInfo.mergeCodePathUsedByOtherApps(dexPath, isUsedByOtherApps,
+ owningPackageName, loadingPackageName);
} else {
// For secondary dex files record the loaderISA and the owner. We'll need
// to know under which user to compile and for what ISA.
- DexUseInfo newData = new DexUseInfo(isUsedByOtherApps, ownerUserId, loaderIsa);
+ DexUseInfo newData = new DexUseInfo(isUsedByOtherApps, ownerUserId,
+ classLoaderContext, loaderIsa);
packageUseInfo.mDexUseInfoMap.put(dexPath, newData);
maybeAddLoadingPackage(owningPackageName, loadingPackageName,
newData.mLoadingPackages);
@@ -129,12 +153,11 @@
if (primaryOrSplit) {
// We have a possible update on the primary apk usage. Merge
// isUsedByOtherApps information and return if there was an update.
- boolean updateLoadingPackages = maybeAddLoadingPackage(owningPackageName,
- loadingPackageName, packageUseInfo.mLoadingPackages);
- return packageUseInfo.merge(isUsedByOtherApps) || updateLoadingPackages;
+ return packageUseInfo.mergeCodePathUsedByOtherApps(
+ dexPath, isUsedByOtherApps, owningPackageName, loadingPackageName);
} else {
DexUseInfo newData = new DexUseInfo(
- isUsedByOtherApps, ownerUserId, loaderIsa);
+ isUsedByOtherApps, ownerUserId, classLoaderContext, loaderIsa);
boolean updateLoadingPackages = maybeAddLoadingPackage(owningPackageName,
loadingPackageName, newData.mLoadingPackages);
@@ -178,8 +201,12 @@
* Convenience method for async writes which does not force the user to pass a useless
* (Void) null.
*/
- public void maybeWriteAsync() {
- maybeWriteAsync((Void) null);
+ /*package*/ void maybeWriteAsync() {
+ maybeWriteAsync(null);
+ }
+
+ /*package*/ void writeNow() {
+ writeInternal(null);
}
@Override
@@ -206,22 +233,18 @@
*
* file_magic_version
* package_name_1
+ * +code_path1
* @ loading_package_1_1, loading_package_1_2...
+ * +code_path2
+ * @ loading_package_2_1, loading_package_2_2...
* #dex_file_path_1_1
- * @ loading_package_1_1_1, loading_package_1_1_2...
* user_1_1, used_by_other_app_1_1, user_isa_1_1_1, user_isa_1_1_2
+ * @ loading_package_1_1_1, loading_package_1_1_2...
+ * class_loader_context_1_1
* #dex_file_path_1_2
- * @ loading_package_1_2_1, loading_package_1_2_2...
* user_1_2, used_by_other_app_1_2, user_isa_1_2_1, user_isa_1_2_2
- * ...
- * package_name_2
- * @ loading_package_2_1, loading_package_2_1_2...
- * #dex_file_path_2_1
- * @ loading_package_2_1_1, loading_package_2_1_2...
- * user_2_1, used_by_other_app_2_1, user_isa_2_1_1, user_isa_2_1_2
- * #dex_file_path_2_2,
- * @ loading_package_2_2_1, loading_package_2_2_2...
- * user_2_2, used_by_other_app_2_2, user_isa_2_2_1, user_isa_2_2_2
+ * @ loading_package_1_2_1, loading_package_1_2_2...
+ * class_loader_context_1_2
* ...
*/
/* package */ void write(Writer out) {
@@ -238,26 +261,31 @@
// Write the package line.
String packageName = pEntry.getKey();
PackageUseInfo packageUseInfo = pEntry.getValue();
+ fpw.println(packageName);
- fpw.println(String.join(SPLIT_CHAR, packageName,
- writeBoolean(packageUseInfo.mIsUsedByOtherApps)));
- fpw.println(LOADING_PACKAGE_CHAR +
- String.join(SPLIT_CHAR, packageUseInfo.mLoadingPackages));
+ // Write the code paths used by other apps.
+ for (Map.Entry<String, Set<String>> codeEntry :
+ packageUseInfo.mCodePathsUsedByOtherApps.entrySet()) {
+ String codePath = codeEntry.getKey();
+ Set<String> loadingPackages = codeEntry.getValue();
+ fpw.println(CODE_PATH_LINE_CHAR + codePath);
+ fpw.println(LOADING_PACKAGE_CHAR + String.join(SPLIT_CHAR, loadingPackages));
+ }
// Write dex file lines.
for (Map.Entry<String, DexUseInfo> dEntry : packageUseInfo.mDexUseInfoMap.entrySet()) {
String dexPath = dEntry.getKey();
DexUseInfo dexUseInfo = dEntry.getValue();
fpw.println(DEX_LINE_CHAR + dexPath);
- fpw.println(LOADING_PACKAGE_CHAR +
- String.join(SPLIT_CHAR, dexUseInfo.mLoadingPackages));
-
fpw.print(String.join(SPLIT_CHAR, Integer.toString(dexUseInfo.mOwnerUserId),
- writeBoolean(dexUseInfo.mIsUsedByOtherApps)));
+ writeBoolean(dexUseInfo.mIsUsedByOtherApps)));
for (String isa : dexUseInfo.mLoaderIsas) {
fpw.print(SPLIT_CHAR + isa);
}
fpw.println();
+ fpw.println(LOADING_PACKAGE_CHAR
+ + String.join(SPLIT_CHAR, dexUseInfo.mLoadingPackages));
+ fpw.println(dexUseInfo.getClassLoaderContext());
}
}
fpw.flush();
@@ -299,7 +327,7 @@
}
}
- String s;
+ String line;
String currentPackage = null;
PackageUseInfo currentPackageData = null;
@@ -307,39 +335,41 @@
for (String abi : Build.SUPPORTED_ABIS) {
supportedIsas.add(VMRuntime.getInstructionSet(abi));
}
- while ((s = in.readLine()) != null) {
- if (s.startsWith(DEX_LINE_CHAR)) {
+ while ((line = in.readLine()) != null) {
+ if (line.startsWith(DEX_LINE_CHAR)) {
// This is the start of the the dex lines.
- // We expect two lines for each dex entry:
+ // We expect 4 lines for each dex entry:
// #dexPaths
+ // @loading_package_1,loading_package_2,...
+ // class_loader_context
// onwerUserId,isUsedByOtherApps,isa1,isa2
if (currentPackage == null) {
throw new IllegalStateException(
"Malformed PackageDexUsage file. Expected package line before dex line.");
}
- // First line is the dex path.
- String dexPath = s.substring(DEX_LINE_CHAR.length());
+ // Line 1 is the dex path.
+ String dexPath = line.substring(DEX_LINE_CHAR.length());
- // In version 2 the second line contains the list of packages that loaded the file.
- List<String> loadingPackages = maybeReadLoadingPackages(in, version);
-
- // Next line is the dex data.
- s = in.readLine();
- if (s == null) {
- throw new IllegalStateException("Could not find dexUseInfo for line: " + s);
+ // Line 2 is the dex data: (userId, isUsedByOtherApps, isa).
+ line = in.readLine();
+ if (line == null) {
+ throw new IllegalStateException("Could not find dexUseInfo line");
}
-
- // We expect at least 3 elements (isUsedByOtherApps, userId, isa).
- String[] elems = s.split(SPLIT_CHAR);
+ String[] elems = line.split(SPLIT_CHAR);
if (elems.length < 3) {
- throw new IllegalStateException("Invalid PackageDexUsage line: " + s);
+ throw new IllegalStateException("Invalid PackageDexUsage line: " + line);
}
+
+ // In version 2 we added the loading packages and class loader context.
+ Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
+ String classLoaderContext = maybeReadClassLoaderContext(in, version);
+
int ownerUserId = Integer.parseInt(elems[0]);
boolean isUsedByOtherApps = readBoolean(elems[1]);
- DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId);
+ DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId,
+ classLoaderContext, /*isa*/ null);
dexUseInfo.mLoadingPackages.addAll(loadingPackages);
-
for (int i = 2; i < elems.length; i++) {
String isa = elems[i];
if (supportedIsas.contains(isa)) {
@@ -357,17 +387,35 @@
continue;
}
currentPackageData.mDexUseInfoMap.put(dexPath, dexUseInfo);
+ } else if (line.startsWith(CODE_PATH_LINE_CHAR)) {
+ // This is a code path used by other apps line.
+ if (version < PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+ throw new IllegalArgumentException("Unexpected code path line when parsing " +
+ "PackageDexUseData: " + line);
+ }
+
+ // Expects 2 lines:
+ // +code_paths
+ // @loading_packages
+ String codePath = line.substring(CODE_PATH_LINE_CHAR.length());
+ Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
+ currentPackageData.mCodePathsUsedByOtherApps.put(codePath, loadingPackages);
} else {
// This is a package line.
- // We expect it to be: `packageName,isUsedByOtherApps`.
- String[] elems = s.split(SPLIT_CHAR);
- if (elems.length != 2) {
- throw new IllegalStateException("Invalid PackageDexUsage line: " + s);
+ if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+ currentPackage = line;
+ currentPackageData = new PackageUseInfo();
+ } else {
+ // Old version (<2)
+ // We expect it to be: `packageName,isUsedByOtherApps`.
+ String[] elems = line.split(SPLIT_CHAR);
+ if (elems.length != 2) {
+ throw new IllegalStateException("Invalid PackageDexUsage line: " + line);
+ }
+ currentPackage = elems[0];
+ currentPackageData = new PackageUseInfo();
+ currentPackageData.mUsedByOtherAppsBeforeUpgrade = readBoolean(elems[1]);
}
- currentPackage = elems[0];
- currentPackageData = new PackageUseInfo();
- currentPackageData.mIsUsedByOtherApps = readBoolean(elems[1]);
- currentPackageData.mLoadingPackages.addAll(maybeReadLoadingPackages(in, version));
data.put(currentPackage, currentPackageData);
}
}
@@ -379,25 +427,45 @@
}
/**
- * Reads the list of loading packages from the buffer {@parm in} if
+ * Reads the class loader context encoding from the buffer {@code in} if
* {@code version} is at least {PACKAGE_DEX_USAGE_VERSION}.
*/
- private List<String> maybeReadLoadingPackages(BufferedReader in, int version)
+ private String maybeReadClassLoaderContext(BufferedReader in, int version) throws IOException {
+ String context = null;
+ if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
+ context = in.readLine();
+ if (context == null) {
+ throw new IllegalStateException("Could not find the classLoaderContext line.");
+ }
+ }
+ // The context might be empty if we didn't have the chance to update it after a version
+ // upgrade. In this case return the special marker so that we recognize this is an unknown
+ // context.
+ return context == null ? UNKNOWN_CLASS_LOADER_CONTEXT : context;
+ }
+
+ /**
+ * Reads the list of loading packages from the buffer {@code in} if
+ * {@code version} is at least {PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2}.
+ */
+ private Set<String> maybeReadLoadingPackages(BufferedReader in, int version)
throws IOException {
- if (version == PACKAGE_DEX_USAGE_VERSION) {
+ if (version >= PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2) {
String line = in.readLine();
if (line == null) {
throw new IllegalStateException("Could not find the loadingPackages line.");
}
// We expect that most of the times the list of loading packages will be empty.
if (line.length() == LOADING_PACKAGE_CHAR.length()) {
- return Collections.emptyList();
+ return Collections.emptySet();
} else {
- return Arrays.asList(
+ Set<String> result = new HashSet<>();
+ Collections.addAll(result,
line.substring(LOADING_PACKAGE_CHAR.length()).split(SPLIT_CHAR));
+ return result;
}
} else {
- return Collections.emptyList();
+ return Collections.emptySet();
}
}
@@ -411,14 +479,15 @@
}
private boolean isSupportedVersion(int version) {
- return version == PACKAGE_DEX_USAGE_VERSION ||
- version == PACKAGE_DEX_USAGE_SUPPORTED_VERSION_1;
+ return version == PACKAGE_DEX_USAGE_SUPPORTED_VERSION_1
+ || version == PACKAGE_DEX_USAGE_SUPPORTED_VERSION_2;
}
/**
* Syncs the existing data with the set of available packages by removing obsolete entries.
*/
- public void syncData(Map<String, Set<Integer>> packageToUsersMap) {
+ /*package*/ void syncData(Map<String, Set<Integer>> packageToUsersMap,
+ Map<String, Set<String>> packageToCodePaths) {
synchronized (mPackageUseInfoMap) {
Iterator<Map.Entry<String, PackageUseInfo>> pIt =
mPackageUseInfoMap.entrySet().iterator();
@@ -442,8 +511,26 @@
dIt.remove();
}
}
- if (!packageUseInfo.mIsUsedByOtherApps
- && packageUseInfo.mDexUseInfoMap.isEmpty()) {
+
+ // Sync the code paths.
+ Set<String> codePaths = packageToCodePaths.get(packageName);
+ Iterator<Map.Entry<String, Set<String>>> codeIt =
+ packageUseInfo.mCodePathsUsedByOtherApps.entrySet().iterator();
+ while (codeIt.hasNext()) {
+ if (!codePaths.contains(codeIt.next().getKey())) {
+ codeIt.remove();
+ }
+ }
+
+ // In case the package was marked as used by other apps in a previous version
+ // propagate the flag to all the code paths.
+ // See mUsedByOtherAppsBeforeUpgrade docs on why it is important to do it.
+ if (packageUseInfo.mUsedByOtherAppsBeforeUpgrade) {
+ for (String codePath : codePaths) {
+ packageUseInfo.mergeCodePathUsedByOtherApps(codePath, true, null, null);
+ }
+ } else if (!packageUseInfo.isAnyCodePathUsedByOtherApps()
+ && packageUseInfo.mDexUseInfoMap.isEmpty()) {
// The package is not used by other apps and we removed all its dex files
// records. Remove the entire package record as well.
pIt.remove();
@@ -457,14 +544,13 @@
* Clears the {@code usesByOtherApps} marker for the package {@code packageName}.
* @return true if the package usage info was updated.
*/
- public boolean clearUsedByOtherApps(String packageName) {
+ /*package*/ boolean clearUsedByOtherApps(String packageName) {
synchronized (mPackageUseInfoMap) {
PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
- if (packageUseInfo == null || !packageUseInfo.mIsUsedByOtherApps) {
+ if (packageUseInfo == null) {
return false;
}
- packageUseInfo.mIsUsedByOtherApps = false;
- return true;
+ return packageUseInfo.clearCodePathUsedByOtherApps();
}
}
@@ -485,7 +571,7 @@
* @return true if the record was found and actually deleted,
* false if the record doesn't exist
*/
- public boolean removeUserPackage(String packageName, int userId) {
+ /*package*/ boolean removeUserPackage(String packageName, int userId) {
synchronized (mPackageUseInfoMap) {
PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
if (packageUseInfo == null) {
@@ -503,7 +589,8 @@
}
// If no secondary dex info is left and the package is not used by other apps
// remove the data since it is now useless.
- if (packageUseInfo.mDexUseInfoMap.isEmpty() && !packageUseInfo.mIsUsedByOtherApps) {
+ if (packageUseInfo.mDexUseInfoMap.isEmpty()
+ && !packageUseInfo.isAnyCodePathUsedByOtherApps()) {
mPackageUseInfoMap.remove(packageName);
updated = true;
}
@@ -517,7 +604,7 @@
* @return true if the record was found and actually deleted,
* false if the record doesn't exist
*/
- public boolean removeDexFile(String packageName, String dexFile, int userId) {
+ /*package*/ boolean removeDexFile(String packageName, String dexFile, int userId) {
synchronized (mPackageUseInfoMap) {
PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
if (packageUseInfo == null) {
@@ -539,7 +626,7 @@
return false;
}
- public PackageUseInfo getPackageUseInfo(String packageName) {
+ /*package*/ PackageUseInfo getPackageUseInfo(String packageName) {
synchronized (mPackageUseInfoMap) {
PackageUseInfo useInfo = mPackageUseInfoMap.get(packageName);
// The useInfo contains a map for secondary dex files which could be modified
@@ -554,7 +641,7 @@
/**
* Return all packages that contain records of secondary dex files.
*/
- public Set<String> getAllPackagesWithSecondaryDexFiles() {
+ /*package*/ Set<String> getAllPackagesWithSecondaryDexFiles() {
Set<String> packages = new HashSet<>();
synchronized (mPackageUseInfoMap) {
for (Map.Entry<String, PackageUseInfo> entry : mPackageUseInfoMap.entrySet()) {
@@ -592,15 +679,6 @@
throw new IllegalArgumentException("Unknown bool encoding: " + bool);
}
- private boolean contains(int[] array, int elem) {
- for (int i = 0; i < array.length; i++) {
- if (elem == array[i]) {
- return true;
- }
- }
- return false;
- }
-
public String dump() {
StringWriter sw = new StringWriter();
write(sw);
@@ -611,46 +689,94 @@
* Stores data on how a package and its dex files are used.
*/
public static class PackageUseInfo {
- // This flag is for the primary and split apks. It is set to true whenever one of them
- // is loaded by another app.
- private boolean mIsUsedByOtherApps;
+ // The app's code paths that are used by other apps.
+ // The key is the code path and the value is the set of loading packages.
+ private final Map<String, Set<String>> mCodePathsUsedByOtherApps;
// Map dex paths to their data (isUsedByOtherApps, owner id, loader isa).
private final Map<String, DexUseInfo> mDexUseInfoMap;
- // Packages who load this dex file.
- private final Set<String> mLoadingPackages;
+
+ // Keeps track of whether or not this package was used by other apps before
+ // we upgraded to VERSION 4 which records the info for each code path separately.
+ // This is unwanted complexity but without it we risk to profile guide compile
+ // something that supposed to be shared. For example:
+ // 1) we determine that chrome is used by another app
+ // 2) we take an OTA which upgrades the way we keep track of usage data
+ // 3) chrome doesn't get used until the background job executes
+ // 4) as part of the backgound job we now think that chrome is not used by others
+ // and we speed-profile.
+ // 5) as a result the next time someone uses chrome it will extract from apk since
+ // the compiled code will be private.
+ private boolean mUsedByOtherAppsBeforeUpgrade;
public PackageUseInfo() {
- mIsUsedByOtherApps = false;
+ mCodePathsUsedByOtherApps = new HashMap<>();
mDexUseInfoMap = new HashMap<>();
- mLoadingPackages = new HashSet<>();
}
// Creates a deep copy of the `other`.
public PackageUseInfo(PackageUseInfo other) {
- mIsUsedByOtherApps = other.mIsUsedByOtherApps;
+ mCodePathsUsedByOtherApps = new HashMap<>();
+ for (Map.Entry<String, Set<String>> e : other.mCodePathsUsedByOtherApps.entrySet()) {
+ mCodePathsUsedByOtherApps.put(e.getKey(), new HashSet<>(e.getValue()));
+ }
+
mDexUseInfoMap = new HashMap<>();
for (Map.Entry<String, DexUseInfo> e : other.mDexUseInfoMap.entrySet()) {
mDexUseInfoMap.put(e.getKey(), new DexUseInfo(e.getValue()));
}
- mLoadingPackages = new HashSet<>(other.mLoadingPackages);
}
- private boolean merge(boolean isUsedByOtherApps) {
- boolean oldIsUsedByOtherApps = mIsUsedByOtherApps;
- mIsUsedByOtherApps = mIsUsedByOtherApps || isUsedByOtherApps;
- return oldIsUsedByOtherApps != this.mIsUsedByOtherApps;
+ private boolean mergeCodePathUsedByOtherApps(String codePath, boolean isUsedByOtherApps,
+ String owningPackageName, String loadingPackage) {
+ if (!isUsedByOtherApps) {
+ // Nothing to update if the the code path is not used by other apps.
+ return false;
+ }
+
+ boolean newCodePath = false;
+ Set<String> loadingPackages = mCodePathsUsedByOtherApps.get(codePath);
+ if (loadingPackages == null) {
+ loadingPackages = new HashSet<>();
+ mCodePathsUsedByOtherApps.put(codePath, loadingPackages);
+ newCodePath = true;
+ }
+ boolean newLoadingPackage = loadingPackage != null
+ && !loadingPackage.equals(owningPackageName)
+ && loadingPackages.add(loadingPackage);
+ return newCodePath || newLoadingPackage;
}
- public boolean isUsedByOtherApps() {
- return mIsUsedByOtherApps;
+ public boolean isUsedByOtherApps(String codePath) {
+ return mCodePathsUsedByOtherApps.containsKey(codePath);
}
public Map<String, DexUseInfo> getDexUseInfoMap() {
return mDexUseInfoMap;
}
- public Set<String> getLoadingPackages() {
- return mLoadingPackages;
+ public Set<String> getLoadingPackages(String codePath) {
+ return mCodePathsUsedByOtherApps.getOrDefault(codePath, null);
+ }
+
+ public boolean isAnyCodePathUsedByOtherApps() {
+ return !mCodePathsUsedByOtherApps.isEmpty();
+ }
+
+ /**
+ * Clears the usedByOtherApps markers from all code paths.
+ * Returns whether or not there was an update.
+ */
+ /*package*/ boolean clearCodePathUsedByOtherApps() {
+ // Update mUsedByOtherAppsBeforeUpgrade as well to be consistent with
+ // the new data. This is not saved to disk so we don't need to return it.
+ mUsedByOtherAppsBeforeUpgrade = true;
+
+ if (mCodePathsUsedByOtherApps.isEmpty()) {
+ return false;
+ } else {
+ mCodePathsUsedByOtherApps.clear();
+ return true;
+ }
}
}
@@ -660,17 +786,20 @@
public static class DexUseInfo {
private boolean mIsUsedByOtherApps;
private final int mOwnerUserId;
+ // The class loader context for the dex file. This encodes the class loader chain
+ // (class loader type + class path) in a format compatible to dex2oat.
+ // See {@code DexoptUtils.processContextForDexLoad}.
+ private String mClassLoaderContext;
+ // The instructions sets of the applications loading the dex file.
private final Set<String> mLoaderIsas;
// Packages who load this dex file.
private final Set<String> mLoadingPackages;
- public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId) {
- this(isUsedByOtherApps, ownerUserId, null);
- }
-
- public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String loaderIsa) {
+ public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String classLoaderContext,
+ String loaderIsa) {
mIsUsedByOtherApps = isUsedByOtherApps;
mOwnerUserId = ownerUserId;
+ mClassLoaderContext = classLoaderContext;
mLoaderIsas = new HashSet<>();
if (loaderIsa != null) {
mLoaderIsas.add(loaderIsa);
@@ -682,6 +811,7 @@
public DexUseInfo(DexUseInfo other) {
mIsUsedByOtherApps = other.mIsUsedByOtherApps;
mOwnerUserId = other.mOwnerUserId;
+ mClassLoaderContext = other.mClassLoaderContext;
mLoaderIsas = new HashSet<>(other.mLoaderIsas);
mLoadingPackages = new HashSet<>(other.mLoadingPackages);
}
@@ -691,8 +821,24 @@
mIsUsedByOtherApps = mIsUsedByOtherApps || dexUseInfo.mIsUsedByOtherApps;
boolean updateIsas = mLoaderIsas.addAll(dexUseInfo.mLoaderIsas);
boolean updateLoadingPackages = mLoadingPackages.addAll(dexUseInfo.mLoadingPackages);
- return updateIsas || (oldIsUsedByOtherApps != mIsUsedByOtherApps) ||
- updateLoadingPackages;
+
+ String oldClassLoaderContext = mClassLoaderContext;
+ if (UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext)) {
+ // Can happen if we read a previous version.
+ mClassLoaderContext = dexUseInfo.mClassLoaderContext;
+ } else if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(dexUseInfo.mClassLoaderContext)) {
+ // We detected an unsupported context.
+ mClassLoaderContext = UNSUPPORTED_CLASS_LOADER_CONTEXT;
+ } else if (!UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext) &&
+ !Objects.equal(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
+ // We detected a context change.
+ mClassLoaderContext = VARIABLE_CLASS_LOADER_CONTEXT;
+ }
+
+ return updateIsas ||
+ (oldIsUsedByOtherApps != mIsUsedByOtherApps) ||
+ updateLoadingPackages
+ || !Objects.equal(oldClassLoaderContext, mClassLoaderContext);
}
public boolean isUsedByOtherApps() {
@@ -710,5 +856,21 @@
public Set<String> getLoadingPackages() {
return mLoadingPackages;
}
+
+ public String getClassLoaderContext() { return mClassLoaderContext; }
+
+ public boolean isUnsupportedClassLoaderContext() {
+ return UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+ }
+
+ public boolean isUnknownClassLoaderContext() {
+ // The class loader context may be unknown if we loaded the data from a previous version
+ // which didn't save the context.
+ return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+ }
+
+ public boolean isVariableClassLoaderContext() {
+ return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
+ }
}
}
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
index 0b54e5e..0a8635d 100644
--- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
+++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
@@ -18,6 +18,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.ActivityManager;
+import android.app.ActivityThread;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -212,7 +213,9 @@
final String warningMessage = String.format(
mContext.getString(R.string.accessibility_shortcut_toogle_warning),
serviceInfo.getResolveInfo().loadLabel(mContext.getPackageManager()).toString());
- final AlertDialog alertDialog = mFrameworkObjectProvider.getAlertDialogBuilder(mContext)
+ final AlertDialog alertDialog = mFrameworkObjectProvider.getAlertDialogBuilder(
+ // Use SystemUI context so we pick up any theme set in a vendor overlay
+ ActivityThread.currentActivityThread().getSystemUiContext())
.setTitle(R.string.accessibility_shortcut_warning_dialog_title)
.setMessage(warningMessage)
.setCancelable(false)
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e3cf459..ae78d7c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -496,6 +496,7 @@
volatile boolean mEndCallKeyHandled;
volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
volatile boolean mGoingToSleep;
+ volatile boolean mRequestedOrGoingToSleep;
volatile boolean mRecentsVisible;
volatile boolean mPictureInPictureVisible;
// Written by vr manager thread, only read in this class.
@@ -1274,7 +1275,7 @@
if (gestureService != null) {
gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
mTmpBoolean);
- if (mTmpBoolean.value && mGoingToSleep) {
+ if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
}
@@ -1402,17 +1403,14 @@
case SHORT_PRESS_POWER_NOTHING:
break;
case SHORT_PRESS_POWER_GO_TO_SLEEP:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+ goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+ goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+ goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
launchHomeFromHotKey();
break;
@@ -1437,6 +1435,11 @@
}
}
+ private void goToSleep(long eventTime, int reason, int flags) {
+ mRequestedOrGoingToSleep = true;
+ mPowerManager.goToSleep(eventTime, reason, flags);
+ }
+
private void shortPressPowerGoHome() {
launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
if (isKeyguardShowingAndNotOccluded()) {
@@ -1469,8 +1472,7 @@
Settings.Global.THEATER_MODE_ON, 1);
if (mGoToSleepOnButtonPressTheaterMode && interactive) {
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+ goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
}
}
break;
@@ -1553,8 +1555,7 @@
case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+ goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
break;
}
}
@@ -4184,7 +4185,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (event instanceof MotionEvent
@@ -6060,7 +6061,7 @@
}
if ((mEndcallBehavior
& Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
- mPowerManager.goToSleep(event.getEventTime(),
+ goToSleep(event.getEventTime(),
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
isWakeKey = false;
}
@@ -6569,8 +6570,10 @@
@Override
public void startedGoingToSleep(int why) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
- mCameraGestureTriggeredDuringGoingToSleep = false;
+
mGoingToSleep = true;
+ mRequestedOrGoingToSleep = true;
+
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedGoingToSleep(why);
}
@@ -6584,6 +6587,7 @@
MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
mGoingToSleep = false;
+ mRequestedOrGoingToSleep = false;
// We must get this work done here because the power manager will drop
// the wake lock and let the system suspend once this function returns.
@@ -7049,6 +7053,12 @@
// Ignore sensor when demo rotation lock is enabled.
// Note that the dock orientation and HDMI rotation lock override this.
preferredRotation = mDemoRotation;
+ } else if (mPersistentVrModeEnabled) {
+ // While in VR, apps always prefer a portrait rotation. This does not change
+ // any apps that explicitly set landscape, but does cause sensors be ignored,
+ // and ignored any orientation lock that the user has set (this conditional
+ // should remain above the ORIENTATION_LOCKED conditional below).
+ preferredRotation = mPortraitRotation;
} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
// Application just wants to remain locked in the last rotation.
preferredRotation = lastRotation;
@@ -7079,13 +7089,7 @@
|| mAllowAllRotations == 1
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
- // In VrMode, we report the sensor as always being in default orientation so:
- // 1) The orientation doesn't change as the user moves their head.
- // 2) 2D apps within VR show in the device's default orientation.
- // This only overwrites the sensor-provided orientation and does not affect any
- // explicit orientation preferences specified by any activities.
- preferredRotation =
- mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation;
+ preferredRotation = sensorRotation;
} else {
preferredRotation = lastRotation;
}
@@ -7498,8 +7502,7 @@
private void applyLidSwitchState() {
if (mLidState == LID_CLOSED && mLidControlsSleep) {
- mPowerManager.goToSleep(SystemClock.uptimeMillis(),
- PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
+ goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
} else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
mWindowManagerFuncs.lockDeviceNow();
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 56612ad..d0ca57a 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -20,7 +20,10 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.IActivityManager;
+import android.app.KeyguardManager;
import android.app.ProgressDialog;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothManager;
import android.content.BroadcastReceiver;
@@ -28,7 +31,6 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.om.IOverlayManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.AudioAttributes;
@@ -53,8 +55,12 @@
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
+
import com.android.internal.telephony.ITelephony;
+import com.android.server.RescueParty;
+import com.android.server.LocalServices;
import com.android.server.pm.PackageManagerService;
+import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.File;
import java.io.IOException;
@@ -285,43 +291,32 @@
pd.setMessage(context.getText(
com.android.internal.R.string.reboot_to_update_prepare));
} else {
+ if (showSysuiReboot()) {
+ return null;
+ }
pd.setIndeterminate(true);
pd.setMessage(context.getText(
com.android.internal.R.string.reboot_to_update_reboot));
}
} else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
- // Factory reset path. Set the dialog message accordingly.
- pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
- pd.setMessage(context.getText(
- com.android.internal.R.string.reboot_to_reset_message));
- pd.setIndeterminate(true);
- } else if (mReason != null && mReason.equals(PowerManager.SHUTDOWN_USER_REQUESTED)) {
- Dialog d = new Dialog(context);
- d.setContentView(com.android.internal.R.layout.shutdown_dialog);
- d.setCancelable(false);
-
- int color = Color.WHITE;
- try {
- IOverlayManager service = IOverlayManager.Stub.asInterface(
- ServiceManager.getService(Context.OVERLAY_SERVICE));
- if (service.getOverlayInfo("com.android.systemui.theme.lightwallpaper", 0).isEnabled()) {
- color = Color.BLACK;
- }
- } catch (Exception e) {
- // Shutdown UI really shouldn't crash or have strict dependencies on other services.
- Log.w(TAG, "Problem getting overlay state", e);
+ if (RescueParty.isAttemptingFactoryReset()) {
+ // We're not actually doing a factory reset yet; we're rebooting
+ // to ask the user if they'd like to reset, so give them a less
+ // scary dialog message.
+ pd.setTitle(context.getText(com.android.internal.R.string.power_off));
+ pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
+ pd.setIndeterminate(true);
+ } else {
+ // Factory reset path. Set the dialog message accordingly.
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
+ pd.setMessage(context.getText(
+ com.android.internal.R.string.reboot_to_reset_message));
+ pd.setIndeterminate(true);
}
- ProgressBar bar = d.findViewById(com.android.internal.R.id.progress);
- bar.getIndeterminateDrawable().setTint(color);
- ((TextView) d.findViewById(com.android.internal.R.id.text1)).setTextColor(color);
- d.getWindow().getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT;
- d.getWindow().getAttributes().height = ViewGroup.LayoutParams.MATCH_PARENT;
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
- d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
- d.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- d.show();
- return null;
} else {
+ if (showSysuiReboot()) {
+ return null;
+ }
pd.setTitle(context.getText(com.android.internal.R.string.power_off));
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
@@ -333,6 +328,23 @@
return pd;
}
+ private static boolean showSysuiReboot() {
+ Log.d(TAG, "Attempting to use SysUI shutdown UI");
+ try {
+ StatusBarManagerInternal service = LocalServices.getService(
+ StatusBarManagerInternal.class);
+ if (service.showShutdownUi(mReboot, mReason)) {
+ // Sysui will handle shutdown UI.
+ Log.d(TAG, "SysUI handling shutdown UI");
+ return true;
+ }
+ } catch (Exception e) {
+ // If anything went wrong, ignore it and use fallback ui
+ }
+ Log.d(TAG, "SysUI is unavailable");
+ return false;
+ }
+
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
@@ -554,7 +566,7 @@
Thread t = new Thread() {
public void run() {
boolean nfcOff;
- boolean bluetoothOff;
+ boolean bluetoothReadyForShutdown;
boolean radioOff;
final INfcAdapter nfc =
@@ -578,15 +590,15 @@
}
try {
- bluetoothOff = bluetooth == null ||
+ bluetoothReadyForShutdown = bluetooth == null ||
bluetooth.getState() == BluetoothAdapter.STATE_OFF;
- if (!bluetoothOff) {
+ if (!bluetoothReadyForShutdown) {
Log.w(TAG, "Disabling Bluetooth...");
bluetooth.disable(mContext.getPackageName(), false); // disable but don't persist new state
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
- bluetoothOff = true;
+ bluetoothReadyForShutdown = true;
}
try {
@@ -611,14 +623,19 @@
sInstance.setRebootProgress(status, null);
}
- if (!bluetoothOff) {
+ if (!bluetoothReadyForShutdown) {
try {
- bluetoothOff = bluetooth.getState() == BluetoothAdapter.STATE_OFF;
+ // BLE only mode can happen when BT is turned off
+ // We will continue shutting down in such case
+ bluetoothReadyForShutdown =
+ bluetooth.getState() == BluetoothAdapter.STATE_OFF ||
+ bluetooth.getState() == BluetoothAdapter.STATE_BLE_TURNING_OFF ||
+ bluetooth.getState() == BluetoothAdapter.STATE_BLE_ON;
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
- bluetoothOff = true;
+ bluetoothReadyForShutdown = true;
}
- if (bluetoothOff) {
+ if (bluetoothReadyForShutdown) {
Log.i(TAG, "Bluetooth turned off.");
}
}
@@ -645,7 +662,7 @@
}
}
- if (radioOff && bluetoothOff && nfcOff) {
+ if (radioOff && bluetoothReadyForShutdown && nfcOff) {
Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
done[0] = true;
break;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 5e322da..866fdad 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -80,6 +80,8 @@
void setGlobalActionsListener(GlobalActionsListener listener);
void showGlobalActions();
+ boolean showShutdownUi(boolean isReboot, String requestString);
+
public interface GlobalActionsListener {
/**
* Called when sysui starts and connects its status bar, or when the status bar binder
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index ae04b83..d31c230 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@
import android.util.ArrayMap;
import android.util.Slog;
+import com.android.internal.R;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
@@ -329,6 +330,20 @@
} catch (RemoteException ex) {}
}
}
+
+ @Override
+ public boolean showShutdownUi(boolean isReboot, String reason) {
+ if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) {
+ return false;
+ }
+ if (mBar != null) {
+ try {
+ mBar.showShutdownUi(isReboot, reason);
+ return true;
+ } catch (RemoteException ex) {}
+ }
+ return false;
+ }
};
// ================================================================================
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index 88b6d87..a35383f 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -29,6 +29,7 @@
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Message;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -154,20 +155,8 @@
private static final String TV_NOTIFICATION_CHANNEL_ID = "devicestoragemonitor.tv";
- /**
- * Handler that checks the amount of disk space on the device and sends a
- * notification if the device runs low on disk space
- */
- private final Handler mHandler = new Handler(IoThread.get().getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_CHECK:
- check();
- return;
- }
- }
- };
+ private final HandlerThread mHandlerThread;
+ private final Handler mHandler;
private State findOrCreateState(UUID uuid) {
State state = mStates.get(uuid);
@@ -256,6 +245,20 @@
public DeviceStorageMonitorService(Context context) {
super(context);
+
+ mHandlerThread = new HandlerThread(TAG, android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread.start();
+
+ mHandler = new Handler(mHandlerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CHECK:
+ check();
+ return;
+ }
+ }
+ };
}
private static boolean isBootImageOnDisk() {
diff --git a/services/core/java/com/android/server/timezone/PackageTracker.java b/services/core/java/com/android/server/timezone/PackageTracker.java
index 9b49996..24e0fe4 100644
--- a/services/core/java/com/android/server/timezone/PackageTracker.java
+++ b/services/core/java/com/android/server/timezone/PackageTracker.java
@@ -173,8 +173,6 @@
throw logAndThrowRuntimeException("Could not determine update app package details for "
+ mUpdateAppPackageName, e);
}
- // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
- // obtained by the system version it's not clear how to check them.
Slog.d(TAG, "Update app " + mUpdateAppPackageName + " is valid.");
// Validate the data application package.
@@ -187,8 +185,6 @@
throw logAndThrowRuntimeException("Could not determine data app package details for "
+ mDataAppPackageName, e);
}
- // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
- // obtained by the system version it's not clear how to check them.
Slog.d(TAG, "Data app " + mDataAppPackageName + " is valid.");
}
@@ -466,7 +462,6 @@
+ TimeZoneRulesDataContract.AUTHORITY);
return false;
}
- // TODO(nfuller) Add any permissions checks needed.
return true;
}
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 1c5aa60..50f27ed 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -57,7 +57,6 @@
import static android.app.timezone.RulesState.STAGED_OPERATION_UNINSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNKNOWN;
-// TODO(nfuller) Check error handling best practices in the system server.
public final class RulesManagerService extends IRulesManager.Stub {
private static final String TAG = "timezone.RulesManagerService";
@@ -336,7 +335,7 @@
private final CheckToken mCheckToken;
private final ICallback mCallback;
- public UninstallRunnable(CheckToken checkToken, ICallback callback) {
+ UninstallRunnable(CheckToken checkToken, ICallback callback) {
mCheckToken = checkToken;
mCallback = callback;
}
@@ -401,54 +400,85 @@
if ("-format_state".equals(args[0]) && args[1] != null) {
for (char c : args[1].toCharArray()) {
switch (c) {
- case 'p': // Report operation in progress
- pw.println("Operation in progress: "
- + rulesState.isOperationInProgress());
- break;
- case 's': // Report system image rules version
- pw.println("System rules version: "
- + rulesState.getSystemRulesVersion());
- break;
- case 'c': // Report current installation state
- pw.println("Current install state: "
- + distroStatusToString(rulesState.getDistroStatus()));
- break;
- case 'i': // Report currently installed version
- DistroRulesVersion installedRulesVersion =
- rulesState.getInstalledDistroRulesVersion();
- pw.print("Installed rules version: ");
- if (installedRulesVersion == null) {
- pw.println("<None>");
- } else {
- pw.println(installedRulesVersion.toDumpString());
+ case 'p': {
+ // Report operation in progress
+ String value = "Unknown";
+ if (rulesState != null) {
+ value = Boolean.toString(rulesState.isOperationInProgress());
}
+ pw.println("Operation in progress: " + value);
break;
- case 'o': // Report staged operation type
- int stagedOperationType = rulesState.getStagedOperationType();
- pw.println("Staged operation: "
- + stagedOperationToString(stagedOperationType));
+ }
+ case 's': {
+ // Report system image rules version
+ String value = "Unknown";
+ if (rulesState != null) {
+ value = rulesState.getSystemRulesVersion();
+ }
+ pw.println("System rules version: " + value);
break;
- case 't':
+ }
+ case 'c': {
+ // Report current installation state
+ String value = "Unknown";
+ if (rulesState != null) {
+ value = distroStatusToString(rulesState.getDistroStatus());
+ }
+ pw.println("Current install state: " + value);
+ break;
+ }
+ case 'i': {
+ // Report currently installed version
+ String value = "Unknown";
+ if (rulesState != null) {
+ DistroRulesVersion installedRulesVersion =
+ rulesState.getInstalledDistroRulesVersion();
+ if (installedRulesVersion == null) {
+ value = "<None>";
+ } else {
+ value = installedRulesVersion.toDumpString();
+ }
+ }
+ pw.println("Installed rules version: " + value);
+ break;
+ }
+ case 'o': {
+ // Report staged operation type
+ String value = "Unknown";
+ if (rulesState != null) {
+ int stagedOperationType = rulesState.getStagedOperationType();
+ value = stagedOperationToString(stagedOperationType);
+ }
+ pw.println("Staged operation: " + value);
+ break;
+ }
+ case 't': {
// Report staged version (i.e. the one that will be installed next boot
// if the staged operation is an install).
- pw.print("Staged rules version: ");
- DistroRulesVersion stagedDistroRulesVersion =
- rulesState.getStagedDistroRulesVersion();
- if (stagedDistroRulesVersion == null) {
- pw.println("<None>");
- } else {
- pw.println(stagedDistroRulesVersion.toDumpString());
+ String value = "Unknown";
+ if (rulesState != null) {
+ DistroRulesVersion stagedDistroRulesVersion =
+ rulesState.getStagedDistroRulesVersion();
+ if (stagedDistroRulesVersion == null) {
+ value = "<None>";
+ } else {
+ value = stagedDistroRulesVersion.toDumpString();
+ }
}
+ pw.println("Staged rules version: " + value);
break;
- case 'a':
+ }
+ case 'a': {
// Report the active rules version (i.e. the rules in use by the current
// process).
pw.println("Active rules version (ICU, libcore): "
+ ICU.getTZDataVersion() + ","
+ ZoneInfoDB.getInstance().getVersion());
break;
- default:
+ }
+ default: {
pw.println("Unknown option: " + c);
+ }
}
}
return;
diff --git a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java b/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
index b89ce1c..0cf61c0 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
@@ -57,7 +57,6 @@
return true;
}
- // TODO(nfuller): Wake lock required while running in background thread?
@Override
public void execute(Runnable runnable) {
AsyncTask.execute(runnable);
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 69d8ca6..8f50a39 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -24,6 +24,7 @@
import android.service.vr.IVrManager;
import android.util.Log;
import android.view.Surface;
+import android.view.WindowManagerInternal;
import com.android.server.vr.VrManagerService;
@@ -74,6 +75,7 @@
public static final int MIN_VR_DISPLAY_DPI = 1;
private final ActivityManagerInternal mActivityManagerInternal;
+ private final WindowManagerInternal mWindowManagerInternal;
private final DisplayManager mDisplayManager;
private final IVrManager mVrManager;
private final Object mVdLock = new Object();
@@ -103,9 +105,11 @@
private boolean mBootsToVr = false; // The device boots into VR (standalone VR device)
public Vr2dDisplay(DisplayManager displayManager,
- ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
+ ActivityManagerInternal activityManagerInternal,
+ WindowManagerInternal windowManagerInternal, IVrManager vrManager) {
mDisplayManager = displayManager;
mActivityManagerInternal = activityManagerInternal;
+ mWindowManagerInternal = windowManagerInternal;
mVrManager = vrManager;
mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH;
mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT;
@@ -296,13 +300,12 @@
UNIQUE_DISPLAY_ID);
if (mVirtualDisplay != null) {
- mActivityManagerInternal.setVr2dDisplayId(
- mVirtualDisplay.getDisplay().getDisplayId());
+ updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
// Now create the ImageReader to supply a Surface to the new virtual display.
startImageReader();
} else {
Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
- mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+ updateDisplayId(INVALID_DISPLAY);
return;
}
}
@@ -310,6 +313,11 @@
Log.i(TAG, "VD created: " + mVirtualDisplay);
}
+ private void updateDisplayId(int displayId) {
+ mActivityManagerInternal.setVr2dDisplayId(displayId);
+ mWindowManagerInternal.setVr2dDisplayId(displayId);
+ }
+
/**
* Stops the virtual display with a {@link #STOP_VIRTUAL_DISPLAY_DELAY_MILLIS} timeout.
* The timeout prevents the virtual display from bouncing in cases where VrMode goes in and out
@@ -325,7 +333,7 @@
} else {
Log.i(TAG, "Stopping Virtual Display");
synchronized (mVdLock) {
- mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+ updateDisplayId(INVALID_DISPLAY);
setSurfaceLocked(null); // clean up and release the surface first.
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 74c1b24..b6b964b 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -58,6 +58,7 @@
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.WindowManagerInternal;
import com.android.internal.R;
import com.android.internal.util.DumpUtils;
@@ -633,8 +634,11 @@
DisplayManager dm =
(DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
- ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
- mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager);
+ mVr2dDisplay = new Vr2dDisplay(
+ dm,
+ LocalServices.getService(ActivityManagerInternal.class),
+ LocalServices.getService(WindowManagerInternal.class),
+ mVrManager);
mVr2dDisplay.init(getContext(), mBootsToVr);
IntentFilter intentFilter = new IntentFilter();
@@ -1125,8 +1129,8 @@
private void setPersistentVrModeEnabled(boolean enabled) {
synchronized(mLock) {
setPersistentModeAndNotifyListenersLocked(enabled);
- // Disabling persistent mode when not showing a VR should disable the overall vr mode.
- if (!enabled && mCurrentVrModeComponent == null) {
+ // Disabling persistent mode should disable the overall vr mode.
+ if (!enabled) {
setVrMode(false, null, 0, -1, null);
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 802054e..46097ed 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -25,6 +25,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
@@ -63,6 +64,7 @@
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IInterface;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -331,11 +333,18 @@
}
}
- private void notifyWallpaperColorsChanged(WallpaperData wallpaper, int which) {
+ private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
boolean needsExtraction;
synchronized (mLock) {
- if (mColorsChangedListeners.getRegisteredCallbackCount() == 0)
+ final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
+ mColorsChangedListeners.get(wallpaper.userId);
+ final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
+ mColorsChangedListeners.get(UserHandle.USER_ALL);
+ // No-op until someone is listening to it.
+ if (emptyCallbackList(currentUserColorListeners) &&
+ emptyCallbackList(userAllColorListeners)) {
return;
+ }
if (DEBUG) {
Slog.v(TAG, "notifyWallpaperColorsChanged " + which);
@@ -346,40 +355,66 @@
// Let's notify the current values, it's fine if it's null, it just means
// that we don't know yet.
- notifyColorListeners(wallpaper.primaryColors, which);
+ notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
if (needsExtraction) {
extractColors(wallpaper);
- notifyColorListeners(wallpaper.primaryColors, which);
+ synchronized (mLock) {
+ // Don't need to notify if nothing changed.
+ if (wallpaper.primaryColors == null) {
+ return;
+ }
+ }
+ notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
}
}
- private void notifyColorListeners(WallpaperColors wallpaperColors, int which) {
- final IWallpaperManagerCallback[] listeners;
+ private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) {
+ return (list == null || list.getRegisteredCallbackCount() == 0);
+ }
+
+ private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which,
+ int userId) {
final IWallpaperManagerCallback keyguardListener;
+ final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners;
+ final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners;
synchronized (mLock) {
- // Make a synchronized copy of the listeners to avoid concurrent list modification.
- int callbackCount = mColorsChangedListeners.beginBroadcast();
- listeners = new IWallpaperManagerCallback[callbackCount];
- for (int i = 0; i < callbackCount; i++) {
- listeners[i] = mColorsChangedListeners.getBroadcastItem(i);
- }
- mColorsChangedListeners.finishBroadcast();
+ currentUserColorListeners = mColorsChangedListeners.get(userId);
+ userAllColorListeners = mColorsChangedListeners.get(UserHandle.USER_ALL);
keyguardListener = mKeyguardListener;
}
- for (int i = 0; i < listeners.length; i++) {
- try {
- listeners[i].onWallpaperColorsChanged(wallpaperColors, which);
- } catch (RemoteException e) {
- // Callback is gone, it's not necessary to unregister it since
- // RemoteCallbackList#getBroadcastItem will take care of it.
+ if (currentUserColorListeners != null) {
+ int count = currentUserColorListeners.beginBroadcast();
+ for (int i = 0; i < count; i++) {
+ try {
+ currentUserColorListeners.getBroadcastItem(i)
+ .onWallpaperColorsChanged(wallpaperColors, which, userId);
+ } catch (RemoteException e) {
+ // Callback is gone, it's not necessary to unregister it since
+ // RemoteCallbackList#getBroadcastItem will take care of it.
+ }
}
+ currentUserColorListeners.finishBroadcast();
+ }
+
+ if (userAllColorListeners != null) {
+ int count = userAllColorListeners.beginBroadcast();
+ for (int i = 0; i < count; i++) {
+ try {
+ userAllColorListeners.getBroadcastItem(i)
+ .onWallpaperColorsChanged(wallpaperColors, which, userId);
+ } catch (RemoteException e) {
+ // Callback is gone, it's not necessary to unregister it since
+ // RemoteCallbackList#getBroadcastItem will take care of it.
+ }
+ }
+ userAllColorListeners.finishBroadcast();
}
if (keyguardListener != null) {
try {
- keyguardListener.onWallpaperColorsChanged(wallpaperColors, which);
+ keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId);
} catch (RemoteException e) {
// Oh well it went away; no big deal
}
@@ -595,7 +630,11 @@
final IPackageManager mIPackageManager;
final MyPackageMonitor mMonitor;
final AppOpsManager mAppOpsManager;
- final RemoteCallbackList<IWallpaperManagerCallback> mColorsChangedListeners;
+ /**
+ * Map of color listeners per user id.
+ * The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
+ */
+ final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> mColorsChangedListeners;
WallpaperData mLastWallpaper;
IWallpaperManagerCallback mKeyguardListener;
boolean mWaitingForUnlock;
@@ -858,11 +897,6 @@
*/
@Override
public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
- // Do not override default color extraction if API isn't implemented.
- if (primaryColors == null) {
- return;
- }
-
int which;
synchronized (mLock) {
// Do not broadcast changes on ImageWallpaper since it's handled
@@ -876,7 +910,7 @@
// Live wallpapers always are system wallpapers.
which = FLAG_SYSTEM;
// It's also the lock screen wallpaper when we don't have a bitmap in there
- WallpaperData lockedWallpaper = mLockWallpaperMap.get(mCurrentUserId);
+ WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
if (lockedWallpaper == null) {
which |= FLAG_LOCK;
}
@@ -906,6 +940,13 @@
}
mPaddingChanged = false;
}
+ try {
+ // This will trigger onComputeColors in the wallpaper engine.
+ // It's fine to be locked in here since the binder is oneway.
+ mEngine.requestWallpaperColors();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to request wallpaper colors", e);
+ }
}
}
@@ -1096,7 +1137,7 @@
mMonitor.register(context, null, UserHandle.ALL, true);
getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
loadSettingsLocked(UserHandle.USER_SYSTEM, false);
- mColorsChangedListeners = new RemoteCallbackList<>();
+ mColorsChangedListeners = new SparseArray<>();
}
private static File getWallpaperDir(int userId) {
@@ -1252,16 +1293,24 @@
}
void switchUser(int userId, IRemoteCallback reply) {
+ WallpaperData systemWallpaper;
+ WallpaperData lockWallpaper;
synchronized (mLock) {
mCurrentUserId = userId;
- WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
- // Not started watching yet, in case wallpaper data was loaded for other reasons.
- if (wallpaper.wallpaperObserver == null) {
- wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
- wallpaper.wallpaperObserver.startWatching();
+ systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ lockWallpaper = mLockWallpaperMap.get(userId);
+ if (lockWallpaper == null) {
+ lockWallpaper = systemWallpaper;
}
- switchWallpaper(wallpaper, reply);
+ // Not started watching yet, in case wallpaper data was loaded for other reasons.
+ if (systemWallpaper.wallpaperObserver == null) {
+ systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
+ systemWallpaper.wallpaperObserver.startWatching();
+ }
+ switchWallpaper(systemWallpaper, reply);
}
+ notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
+ notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
}
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
@@ -1634,16 +1683,30 @@
}
@Override
- public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb) {
+ public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+ userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, true, true, "registerWallpaperColorsCallback", null);
synchronized (mLock) {
- mColorsChangedListeners.register(cb);
+ RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+ mColorsChangedListeners.get(userId);
+ if (userColorsChangedListeners == null) {
+ userColorsChangedListeners = new RemoteCallbackList<>();
+ mColorsChangedListeners.put(userId, userColorsChangedListeners);
+ }
+ userColorsChangedListeners.register(cb);
}
}
@Override
- public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb) {
+ public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+ userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, true, true, "unregisterWallpaperColorsCallback", null);
synchronized (mLock) {
- mColorsChangedListeners.unregister(cb);
+ final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+ mColorsChangedListeners.get(userId);
+ if (userColorsChangedListeners != null) {
+ userColorsChangedListeners.unregister(cb);
+ }
}
}
@@ -1657,23 +1720,25 @@
}
@Override
- public WallpaperColors getWallpaperColors(int which) throws RemoteException {
+ public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException {
if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM");
}
+ userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, false, true, "getWallpaperColors", null);
WallpaperData wallpaperData = null;
boolean shouldExtract;
synchronized (mLock) {
if (which == FLAG_LOCK) {
- wallpaperData = mLockWallpaperMap.get(mCurrentUserId);
+ wallpaperData = mLockWallpaperMap.get(userId);
}
// Try to get the system wallpaper anyway since it might
// also be the lock screen wallpaper
if (wallpaperData == null) {
- wallpaperData = mWallpaperMap.get(mCurrentUserId);
+ wallpaperData = mWallpaperMap.get(userId);
}
if (wallpaperData == null) {
@@ -1872,8 +1937,11 @@
try {
wallpaper.imageWallpaperPending = false;
+ boolean same = changingToSame(name, wallpaper);
if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
- wallpaper.primaryColors = null;
+ if (!same) {
+ wallpaper.primaryColors = null;
+ }
wallpaper.wallpaperId = makeWallpaperIdLocked();
notifyCallbacksLocked(wallpaper);
shouldNotifyColors = true;
@@ -1888,26 +1956,31 @@
}
}
+ private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) {
+ if (wallpaper.connection != null) {
+ if (wallpaper.wallpaperComponent == null) {
+ if (componentName == null) {
+ if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
+ // Still using default wallpaper.
+ return true;
+ }
+ } else if (wallpaper.wallpaperComponent.equals(componentName)) {
+ // Changing to same wallpaper.
+ if (DEBUG) Slog.v(TAG, "same wallpaper");
+ return true;
+ }
+ }
+ return false;
+ }
+
boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
if (DEBUG_LIVE) {
Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
}
// Has the component changed?
- if (!force) {
- if (wallpaper.connection != null) {
- if (wallpaper.wallpaperComponent == null) {
- if (componentName == null) {
- if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
- // Still using default wallpaper.
- return true;
- }
- } else if (wallpaper.wallpaperComponent.equals(componentName)) {
- // Changing to same wallpaper.
- if (DEBUG) Slog.v(TAG, "same wallpaper");
- return true;
- }
- }
+ if (!force && changingToSame(componentName, wallpaper)) {
+ return true;
}
try {
@@ -2234,15 +2307,35 @@
}
private void migrateFromOld() {
- File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
- File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
- if (oldWallpaper.exists()) {
- File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
- oldWallpaper.renameTo(newWallpaper);
- }
- if (oldInfo.exists()) {
- File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
- oldInfo.renameTo(newInfo);
+ // Pre-N, what existed is the one we're now using as the display crop
+ File preNWallpaper = new File(getWallpaperDir(0), WALLPAPER_CROP);
+ // In the very-long-ago, imagery lived with the settings app
+ File originalWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
+ File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
+
+ // Migrations from earlier wallpaper image storage schemas
+ if (preNWallpaper.exists()) {
+ if (!newWallpaper.exists()) {
+ // we've got the 'wallpaper' crop file but not the nominal source image,
+ // so do the simple "just take everything" straight copy of legacy data
+ if (DEBUG) {
+ Slog.i(TAG, "Migrating wallpaper schema");
+ }
+ FileUtils.copyFile(preNWallpaper, newWallpaper);
+ } // else we're in the usual modern case: both source & crop exist
+ } else if (originalWallpaper.exists()) {
+ // VERY old schema; make sure things exist and are in the right place
+ if (DEBUG) {
+ Slog.i(TAG, "Migrating antique wallpaper schema");
+ }
+ File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
+ if (oldInfo.exists()) {
+ File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
+ oldInfo.renameTo(newInfo);
+ }
+
+ FileUtils.copyFile(originalWallpaper, preNWallpaper);
+ originalWallpaper.renameTo(newWallpaper);
}
}
@@ -2303,12 +2396,12 @@
JournaledFile journal = makeJournaledFile(userId);
FileInputStream stream = null;
File file = journal.chooseForRead();
- if (!file.exists()) {
- // This should only happen one time, when upgrading from a legacy system
- migrateFromOld();
- }
+
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
+ // Do this once per boot
+ migrateFromOld();
+
wallpaper = new WallpaperData(userId, WALLPAPER, WALLPAPER_CROP);
wallpaper.allowBackup = true;
mWallpaperMap.put(userId, wallpaper);
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 78f2195..805250a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -17,7 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -539,7 +539,7 @@
WindowState windowState = visibleWindows.valueAt(i);
if ((windowState.mAttrs.type == TYPE_MAGNIFICATION_OVERLAY)
|| ((windowState.mAttrs.privateFlags
- & PRIVATE_FLAG_NO_MAGNIFICATION_REGION_EFFECT) != 0)) {
+ & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index f3a09ed..ddbbde1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -198,6 +198,14 @@
return animation != null || mAppToken.inPendingTransaction;
}
+ /**
+ * @return whether an animation is about to start, i.e. the animation is set already but we
+ * haven't processed the first frame yet.
+ */
+ boolean isAnimationStarting() {
+ return animation != null && !animating;
+ }
+
public int getTransit() {
return mTransit;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 84fafe2..e9696d2 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -487,9 +487,8 @@
}
final WindowState mainWin = mContainer.findMainWindow();
- if (mainWin != null && mainWin.isVisible() && mainWin.isDrawnLw()) {
- // App already has a visible window that is drawn...why would you want a starting
- // window?
+ if (mainWin != null && mainWin.mWinAnimator.getShown()) {
+ // App already has a visible window...why would you want a starting window?
return false;
}
@@ -612,23 +611,7 @@
return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
}
- /**
- * Remove starting window if the app is currently hidden. It is possible the starting window is
- * part of its app exit transition animation in which case we delay hiding the app token. The
- * method allows for removal when window manager has set the app token to hidden.
- */
- public void removeHiddenStartingWindow() {
- synchronized (mWindowMap) {
- if (!mContainer.hidden) {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Starting window app still visible."
- + " Ignoring remove request.");
- return;
- }
- removeStartingWindow();
- }
- }
-
- void removeStartingWindow() {
+ public void removeStartingWindow() {
synchronized (mWindowMap) {
if (mContainer.startingWindow == null) {
if (mContainer.startingData != null) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 63890bf..2e4de8c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -193,6 +193,11 @@
Task mLastParent;
+ /**
+ * See {@link #canTurnScreenOn()}
+ */
+ private boolean mCanTurnScreenOn = true;
+
AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -290,7 +295,7 @@
boolean nowGone = mReportedVisibilityResults.nowGone;
boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
- boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+ boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !hidden;
if (!nowGone) {
// If the app is not yet gone, then it can only become visible/drawn.
if (!nowDrawn) {
@@ -448,7 +453,6 @@
mChildren.get(i).mWinAnimator.hide("immediately hidden");
}
SurfaceControl.closeTransaction();
- removeStartingWindow();
}
if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
@@ -526,12 +530,6 @@
return super.checkCompleteDeferredRemoval();
}
- private void removeStartingWindow() {
- if (startingData != null && getController() != null) {
- getController().removeStartingWindow();
- }
- }
-
void onRemovedFromDisplay() {
if (mRemovingFromDisplay) {
return;
@@ -559,7 +557,9 @@
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
+ this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
- removeStartingWindow();
+ if (startingData != null && getController() != null) {
+ getController().removeStartingWindow();
+ }
// If this window was animating, then we need to ensure that the app transition notifies
// that animations have completed in WMS.handleAnimatingStoppedAndTransitionLocked(), so
@@ -649,6 +649,8 @@
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
+ " " + this);
mAppStopped = false;
+ // Allow the window to turn the screen on once the app is resumed again.
+ setCanTurnScreenOn(true);
if (!wasStopped) {
destroySurfaces(true /*cleanupOnResume*/);
}
@@ -1311,7 +1313,7 @@
// going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
// an Activity in another task being started in the wrong orientation during the transition.
if (!(sendingToBottom || mService.mClosingApps.contains(this))
- && (isVisible() || mService.mOpeningApps.contains(this))) {
+ && (isVisible() || mService.mOpeningApps.contains(this) || isOnTop())) {
return mOrientation;
}
@@ -1646,6 +1648,24 @@
}
/**
+ * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+ */
+ void setCanTurnScreenOn(boolean canTurnScreenOn) {
+ mCanTurnScreenOn = canTurnScreenOn;
+ }
+
+ /**
+ * Indicates whether the current launch can turn the screen on. This is to prevent multiple
+ * relayouts from turning the screen back on. The screen should only turn on at most
+ * once per activity resume.
+ *
+ * @return true if the screen can be turned on.
+ */
+ boolean canTurnScreenOn() {
+ return mCanTurnScreenOn;
+ }
+
+ /**
* Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
* the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
* we can't take a snapshot for other reasons, for example, if we have a secure window.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a37b2e5..5bc4a6b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1183,7 +1183,6 @@
final int dh = displayInfo.logicalHeight;
config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
Configuration.ORIENTATION_LANDSCAPE;
- config.setRotation(displayInfo.rotation);
config.screenWidthDp =
(int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
@@ -2682,7 +2681,7 @@
if (!w.getOrientationChanging()) {
return;
}
- w.setOrientationChanging(false);
+ w.orientationChangeTimedOut();
w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
- mService.mDisplayFreezeTime);
Slog.w(TAG_WM, "Force clearing orientation change: " + w);
@@ -3309,6 +3308,13 @@
setLayoutNeeded();
}
+
+ @Override
+ boolean isOnTop() {
+ // Considered always on top
+ return true;
+ }
+
@Override
void positionChildAt(int position, TaskStack child, boolean includingParents) {
if (StackId.isAlwaysOnTop(child.mStackId) && position != POSITION_TOP) {
diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
index 6b0e4c9..484987e 100644
--- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java
+++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
@@ -36,11 +36,11 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
try {
if (event instanceof MotionEvent
&& (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- final MotionEvent motionEvent = (MotionEvent)event;
+ final MotionEvent motionEvent = (MotionEvent) event;
PointerEventListener[] listeners;
synchronized (mListeners) {
if (mListenersArray == null) {
@@ -50,7 +50,7 @@
listeners = mListenersArray;
}
for (int i = 0; i < listeners.length; ++i) {
- listeners[i].onPointerEvent(motionEvent);
+ listeners[i].onPointerEvent(motionEvent, displayId);
}
}
} finally {
diff --git a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
index 0508fdf..a12c2c4 100644
--- a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
+++ b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
@@ -32,7 +32,7 @@
// the surface control.
//
// See cts/hostsidetests/../../SurfaceTraceReceiver.java for parsing side.
-class RemoteSurfaceTrace extends SurfaceControl {
+class RemoteSurfaceTrace extends SurfaceControlWithBackground {
static final String TAG = "RemoteSurfaceTrace";
final FileDescriptor mWriteFd;
@@ -41,7 +41,8 @@
final WindowManagerService mService;
final WindowState mWindow;
- RemoteSurfaceTrace(FileDescriptor fd, SurfaceControl wrapped, WindowState window) {
+ RemoteSurfaceTrace(FileDescriptor fd, SurfaceControlWithBackground wrapped,
+ WindowState window) {
super(wrapped);
mWriteFd = fd;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75b..7bcad9f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -18,6 +18,7 @@
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.hardware.power.V1_0.PowerHint;
import android.os.Binder;
import android.os.Debug;
@@ -51,6 +52,7 @@
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_NONE;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
@@ -243,12 +245,24 @@
displayId, displayInfo);
mService.configureDisplayPolicyLocked(dc);
- // TODO(multi-display): Create an input channel for each display with touch capability.
- if (displayId == DEFAULT_DISPLAY && mService.canDispatchPointerEvents()) {
- dc.mTapDetector = new TaskTapPointerEventListener(
- mService, dc);
+ // Tap Listeners are supported for:
+ // 1. All physical displays (multi-display).
+ // 2. VirtualDisplays that support virtual touch input. (Only VR for now)
+ // TODO(multi-display): Support VirtualDisplays with no virtual touch input.
+ if ((display.getType() != Display.TYPE_VIRTUAL
+ || (display.getType() == Display.TYPE_VIRTUAL
+ // Only VR VirtualDisplays
+ && displayId == mService.mVr2dDisplayId))
+ && mService.canDispatchPointerEvents()) {
+ if (DEBUG_DISPLAY) {
+ Slog.d(TAG,
+ "Registering PointerEventListener for DisplayId: " + displayId);
+ }
+ dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
mService.registerPointerEventListener(dc.mTapDetector);
- mService.registerPointerEventListener(mService.mMousePositionTracker);
+ if (displayId == DEFAULT_DISPLAY) {
+ mService.registerPointerEventListener(mService.mMousePositionTracker);
+ }
}
}
@@ -754,6 +768,15 @@
} else {
mUpdateRotation = false;
}
+ // Update rotation of VR virtual display separately. Currently this is the only kind of
+ // secondary display that can be rotated because of the single-display limitations in
+ // PhoneWindowManager.
+ final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
+ ? getDisplayContent(mService.mVr2dDisplayId) : null;
+ if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
+ mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
+ .sendToTarget();
+ }
}
if (mService.mWaitingForDrawnCallback != null ||
diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
new file mode 100644
index 0000000..85ea3c0
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
@@ -0,0 +1,311 @@
+/*
+ * 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.wm;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+/**
+ * SurfaceControl extension that has background sized to match its container.
+ */
+class SurfaceControlWithBackground extends SurfaceControl {
+ // SurfaceControl that holds the background behind opaque letterboxed app windows.
+ private SurfaceControl mBackgroundControl;
+
+ // Flags that define whether the background should be shown.
+ private boolean mOpaque;
+ private boolean mVisible;
+
+ // Way to communicate with corresponding window.
+ private WindowSurfaceController mWindowSurfaceController;
+
+ // Rect to hold task bounds when computing metrics for background.
+ private Rect mTmpContainerRect = new Rect();
+
+ // Last metrics applied to the main SurfaceControl.
+ private float mLastWidth, mLastHeight;
+ private float mLastDsDx = 1, mLastDsDy = 1;
+ private float mLastX, mLastY;
+
+ public SurfaceControlWithBackground(SurfaceControlWithBackground other) {
+ super(other);
+ mBackgroundControl = other.mBackgroundControl;
+ mOpaque = other.mOpaque;
+ mVisible = other.mVisible;
+ mWindowSurfaceController = other.mWindowSurfaceController;
+ }
+
+ public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format,
+ int flags, int windowType, int ownerUid,
+ WindowSurfaceController windowSurfaceController) throws OutOfResourcesException {
+ super(s, name, w, h, format, flags, windowType, ownerUid);
+
+ // We should only show background when the window is letterboxed in a task.
+ if (!windowSurfaceController.mAnimator.mWin.isLetterboxedAppWindow()) {
+ return;
+ }
+ mWindowSurfaceController = windowSurfaceController;
+ mLastWidth = w;
+ mLastHeight = h;
+ mOpaque = (flags & SurfaceControl.OPAQUE) != 0;
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl = new SurfaceControl(s, "Background for - " + name,
+ mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE,
+ flags | SurfaceControl.FX_SURFACE_DIM);
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ super.setAlpha(alpha);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setAlpha(alpha);
+ }
+
+ @Override
+ public void setLayer(int zorder) {
+ super.setLayer(zorder);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ // TODO: Use setRelativeLayer(Integer.MIN_VALUE) when it's fixed.
+ mBackgroundControl.setLayer(zorder - 1);
+ }
+
+ @Override
+ public void setPosition(float x, float y) {
+ super.setPosition(x, y);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mLastX = x;
+ mLastY = y;
+ updateBgPosition();
+ }
+
+ private void updateBgPosition() {
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+ final float offsetX = (mTmpContainerRect.left - winFrame.left) * mLastDsDx;
+ final float offsetY = (mTmpContainerRect.top - winFrame.top) * mLastDsDy;
+ mBackgroundControl.setPosition(mLastX + offsetX, mLastY + offsetY);
+ }
+
+ @Override
+ public void setSize(int w, int h) {
+ super.setSize(w, h);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mLastWidth = w;
+ mLastHeight = h;
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setSize(mTmpContainerRect.width(), mTmpContainerRect.height());
+ }
+
+ @Override
+ public void setWindowCrop(Rect crop) {
+ super.setWindowCrop(crop);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
+ // We're animating and cropping window, compute the appropriate crop for background.
+ calculateBgCrop(crop);
+ mBackgroundControl.setWindowCrop(mTmpContainerRect);
+ } else {
+ // When not animating just set crop to container rect.
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setWindowCrop(mTmpContainerRect);
+ }
+ }
+
+ @Override
+ public void setFinalCrop(Rect crop) {
+ super.setFinalCrop(crop);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
+ // We're animating and cropping window, compute the appropriate crop for background.
+ calculateBgCrop(crop);
+ mBackgroundControl.setFinalCrop(mTmpContainerRect);
+ } else {
+ // When not animating just set crop to container rect.
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setFinalCrop(mTmpContainerRect);
+ }
+ }
+
+ /** Compute background crop based on current animation progress for main surface control. */
+ private void calculateBgCrop(Rect crop) {
+ // Track overall progress of animation by computing cropped portion of status bar.
+ final Rect contentInsets = mWindowSurfaceController.mAnimator.mWin.mContentInsets;
+ float d = contentInsets.top == 0 ? 0 : (float) crop.top / contentInsets.top;
+
+ // Compute additional offset for the background when app window is positioned not at (0,0).
+ // E.g. landscape with navigation bar on the left.
+ final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+ final int offsetX = (int) (winFrame.left * mLastDsDx * d + 0.5);
+ final int offsetY = (int) (winFrame.top * mLastDsDy * d + 0.5);
+
+ // Compute new scaled width and height for background that will depend on current animation
+ // progress. Those consist of current crop rect for the main surface + scaled areas outside
+ // of letterboxed area.
+ // TODO: Because the progress is computed with low precision we're getting smaller values
+ // for background width/height then screen size at the end of the animation. Will round when
+ // the value is smaller then some empiric epsilon. However, this should be fixed by
+ // computing correct frames for letterboxed windows in WindowState.
+ d = d < 0.02f ? 0 : d;
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ final int backgroundWidth =
+ (int) (crop.width() + (mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+ final int backgroundHeight =
+ (int) (crop.height() + (mTmpContainerRect.height() - mLastHeight) * (1 - d) + 0.5);
+
+ mTmpContainerRect.set(crop);
+ // Make sure that part of background to left/top is visible and scaled.
+ mTmpContainerRect.offset(offsetX, offsetY);
+ // Set correct width/height, so that area to right/bottom is cropped properly.
+ mTmpContainerRect.right = mTmpContainerRect.left + backgroundWidth;
+ mTmpContainerRect.bottom = mTmpContainerRect.top + backgroundHeight;
+ }
+
+ @Override
+ public void setLayerStack(int layerStack) {
+ super.setLayerStack(layerStack);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setLayerStack(layerStack);
+ }
+
+ @Override
+ public void setOpaque(boolean isOpaque) {
+ super.setOpaque(isOpaque);
+ mOpaque = isOpaque;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void setSecure(boolean isSecure) {
+ super.setSecure(isSecure);
+ }
+
+ @Override
+ public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
+ super.setMatrix(dsdx, dtdx, dtdy, dsdy);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
+ mLastDsDx = dsdx;
+ mLastDsDy = dsdy;
+ updateBgPosition();
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ mVisible = false;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void show() {
+ super.show();
+ mVisible = true;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.destroy();
+ }
+
+ @Override
+ public void release() {
+ super.release();
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.release();
+ }
+
+ @Override
+ public void setTransparentRegionHint(Region region) {
+ super.setTransparentRegionHint(region);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setTransparentRegionHint(region);
+ }
+
+ @Override
+ public void deferTransactionUntil(IBinder handle, long frame) {
+ super.deferTransactionUntil(handle, frame);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.deferTransactionUntil(handle, frame);
+ }
+
+ @Override
+ public void deferTransactionUntil(Surface barrier, long frame) {
+ super.deferTransactionUntil(barrier, frame);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.deferTransactionUntil(barrier, frame);
+ }
+
+ private void updateBackgroundVisibility() {
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (mOpaque && mVisible) {
+ mBackgroundControl.show();
+ } else {
+ mBackgroundControl.hide();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 0c68e2c..c58212c 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -133,7 +133,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
if (!(event instanceof MotionEvent)
|| (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
return;
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index dd9ba73..42a2d9d 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -24,6 +24,7 @@
import com.android.server.wm.WindowManagerService.H;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.PointerIcon.TYPE_NOT_SPECIFIED;
import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
@@ -45,6 +46,13 @@
}
@Override
+ public void onPointerEvent(MotionEvent motionEvent, int displayId) {
+ if (displayId == getDisplayId()) {
+ onPointerEvent(motionEvent);
+ }
+ }
+
+ @Override
public void onPointerEvent(MotionEvent motionEvent) {
final int action = motionEvent.getAction();
switch (action & MotionEvent.ACTION_MASK) {
@@ -104,4 +112,8 @@
mTouchExcludeRegion.set(newRegion);
}
}
+
+ private int getDisplayId() {
+ return mDisplayContent.getDisplayId();
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fe5b7f2..079ae40 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -33,7 +33,6 @@
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
-import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
import com.android.server.AnimationThread;
import java.io.PrintWriter;
@@ -134,26 +133,38 @@
* sure other threads can make progress if this happens.
*/
private void animate(long frameTimeNs) {
- boolean transactionOpen = false;
- try {
- synchronized (mService.mWindowMap) {
- if (!mInitialized) {
- return;
- }
- mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
- mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
- mAnimating = false;
- mAppWindowAnimating = false;
- if (DEBUG_WINDOW_TRACE) {
- Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
- }
+ synchronized (mService.mWindowMap) {
+ if (!mInitialized) {
+ return;
+ }
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
- mService.openSurfaceTransaction();
- transactionOpen = true;
- SurfaceControl.setAnimationTransaction();
+ // Schedule next frame already such that back-pressure happens continuously
+ scheduleAnimation();
+ }
+ // Simulate back-pressure by opening and closing an empty animation transaction. This makes
+ // sure that an animation frame is at least presented once on the screen. We do this outside
+ // of the regular transaction such that we can avoid holding the window manager lock in case
+ // we receive back-pressure from SurfaceFlinger. Since closing an animation transaction
+ // without the window manager locks leads to ordering issues (as the transaction will be
+ // processed only at the beginning of the next frame which may result in another transaction
+ // that was executed later in WM side gets executed first on SF side), we don't update any
+ // Surface properties here such that reordering doesn't cause issues.
+ mService.executeEmptyAnimationTransaction();
+
+ synchronized (mService.mWindowMap) {
+ mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
+ mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
+ mAnimating = false;
+ mAppWindowAnimating = false;
+ if (DEBUG_WINDOW_TRACE) {
+ Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
+ }
+
+ if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
+ mService.openSurfaceTransaction();
+ try {
final AccessibilityController accessibilityController =
mService.mAccessibilityController;
final int numDisplays = mDisplayContentsAnimators.size();
@@ -216,27 +227,20 @@
mAnimating |= mService.mDragState.stepAnimationLocked(mCurrentTime);
}
- if (mAnimating) {
- mService.scheduleAnimationLocked();
+ if (!mAnimating) {
+ cancelAnimation();
}
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
}
- }
- } catch (RuntimeException e) {
- Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
- } finally {
- if (transactionOpen) {
-
- // Do not hold window manager lock while closing the transaction, as this might be
- // blocking until the next frame, which can lead to total lock starvation.
- mService.closeSurfaceTransaction(false /* withLockHeld */);
+ } catch (RuntimeException e) {
+ Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+ } finally {
+ mService.closeSurfaceTransaction();
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
}
- }
- synchronized (mService.mWindowMap) {
boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
boolean doRequest = false;
if (mBulkUpdateParams != 0) {
@@ -404,6 +408,13 @@
}
}
+ private void cancelAnimation() {
+ if (mAnimationFrameCallbackScheduled) {
+ mAnimationFrameCallbackScheduled = false;
+ mChoreographer.removeFrameCallback(mAnimationFrameCallback);
+ }
+ }
+
private class DisplayContentsAnimator {
ScreenRotationAnimation mScreenRotationAnimation = null;
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 600bc5c..3df73d7 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -472,6 +472,13 @@
return false;
}
+ /**
+a * Returns whether this child is on top of the window hierarchy.
+ */
+ boolean isOnTop() {
+ return getParent().getTopChild() == this && getParent().isOnTop();
+ }
+
/** Returns the top child container. */
E getTopChild() {
return mChildren.peekLast();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f0ac39a..5c664c2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -79,6 +79,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -357,6 +358,8 @@
final private KeyguardDisableHandler mKeyguardDisableHandler;
boolean mKeyguardGoingAway;
+ // VR Vr2d Display Id.
+ int mVr2dDisplayId = INVALID_DISPLAY;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -767,7 +770,7 @@
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (mDragState == null) {
@@ -908,29 +911,16 @@
}
}
- void closeSurfaceTransaction() {
- closeSurfaceTransaction(true /* withLockHeld */);
- }
-
/**
* Closes a surface transaction.
- *
- * @param withLockHeld Whether to acquire the window manager while doing so. In some cases
- * holding the lock my lead to starvation in WM in case closeTransaction
- * blocks and we call it repeatedly, like we do for animations.
*/
- void closeSurfaceTransaction(boolean withLockHeld) {
+ void closeSurfaceTransaction() {
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
synchronized (mWindowMap) {
if (mRoot.mSurfaceTraceEnabled) {
mRoot.mRemoteEventTrace.closeSurfaceTransaction();
}
- if (withLockHeld) {
- SurfaceControl.closeTransaction();
- }
- }
- if (!withLockHeld) {
SurfaceControl.closeTransaction();
}
} finally {
@@ -938,6 +928,34 @@
}
}
+ /**
+ * Executes an empty animation transaction without holding the WM lock to simulate
+ * back-pressure. See {@link WindowAnimator#animate} why this is needed.
+ */
+ void executeEmptyAnimationTransaction() {
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
+ synchronized (mWindowMap) {
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.openSurfaceTransaction();
+ }
+ SurfaceControl.openTransaction();
+ SurfaceControl.setAnimationTransaction();
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+ }
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
+ SurfaceControl.closeTransaction();
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
+
/** Listener to notify activity manager about app transitions. */
final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
= new WindowManagerInternal.AppTransitionListener() {
@@ -3477,21 +3495,11 @@
}
if (!mBootAnimationStopped) {
- // Do this one time.
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
- try {
- IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
- if (surfaceFlinger != null) {
- Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken("android.ui.ISurfaceComposer");
- surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
- data, null, 0);
- data.recycle();
- }
- } catch (RemoteException ex) {
- Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
- }
+ // stop boot animation
+ // formerly we would just kill the process, but we now ask it to exit so it
+ // can choose where to stop the animation.
+ SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
@@ -3500,6 +3508,20 @@
return;
}
+ try {
+ IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+ if (surfaceFlinger != null) {
+ Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
+ data, null, 0);
+ data.recycle();
+ }
+ } catch (RemoteException ex) {
+ Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
+ }
+
EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
mDisplayEnabled = true;
@@ -6011,9 +6033,9 @@
return;
}
- if (!displayContent.isReady() || !mPolicy.isScreenOn()) {
- // No need to freeze the screen before the display is ready, system is ready, or if
- // the screen is off.
+ if (!displayContent.isReady() || !mPolicy.isScreenOn() || !okToAnimate()) {
+ // No need to freeze the screen before the display is ready, if the screen is off,
+ // or we can't currently animate.
return;
}
@@ -7565,6 +7587,16 @@
accessibilityController.performComputeChangedWindowsNotLocked();
}
}
+
+ @Override
+ public void setVr2dDisplayId(int vr2dDisplayId) {
+ if (DEBUG_DISPLAY) {
+ Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
+ }
+ synchronized (WindowManagerService.this) {
+ mVr2dDisplayId = vr2dDisplayId;
+ }
+ }
}
void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 7decb11..f99d830 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -449,6 +449,17 @@
private boolean mOrientationChanging;
/**
+ * Sometimes in addition to the mOrientationChanging
+ * flag we report that the orientation is changing
+ * due to a mismatch in current and reported configuration.
+ *
+ * In the case of timeout we still need to make sure we
+ * leave the orientation changing state though, so we
+ * use this as a special time out escape hatch.
+ */
+ private boolean mOrientationChangeTimedOut;
+
+ /**
* The orientation during the last visible call to relayout. If our
* current orientation is different, the window can't be ready
* to be shown.
@@ -1224,12 +1235,19 @@
// TODO(b/62846907): Checking against {@link mLastReportedConfiguration} could be flaky as
// this is not necessarily what the client has processed yet. Find a
// better indicator consistent with the client.
- return mOrientationChanging || (isVisible()
- && getConfiguration().orientation != mLastReportedConfiguration.orientation);
+ return (mOrientationChanging || (isVisible()
+ && getConfiguration().orientation != mLastReportedConfiguration.orientation))
+ && !mSeamlesslyRotated
+ && !mOrientationChangeTimedOut;
}
void setOrientationChanging(boolean changing) {
mOrientationChanging = changing;
+ mOrientationChangeTimedOut = false;
+ }
+
+ void orientationChangeTimedOut() {
+ mOrientationChangeTimedOut = true;
}
DisplayContent getDisplayContent() {
@@ -1462,8 +1480,18 @@
@Override
public boolean canAffectSystemUiFlags() {
final boolean shown = mWinAnimator.getShown();
- final boolean exiting = mAnimatingExit || mDestroying
- || mAppToken != null && mAppToken.hidden;
+
+ // We only consider the app to be exiting when the animation has started. After the app
+ // transition is executed the windows are marked exiting before the new windows have been
+ // shown. Thus, wait considering a window to be exiting after the animation has actually
+ // started.
+ final boolean appAnimationStarting = mAppToken != null
+ && mAppToken.mAppAnimator.isAnimationStarting();
+ final boolean exitingSelf = mAnimatingExit && (!mWinAnimator.isAnimationStarting()
+ && !appAnimationStarting);
+ final boolean appExiting = mAppToken != null && mAppToken.hidden && !appAnimationStarting;
+
+ final boolean exiting = exitingSelf || mDestroying || appExiting;
final boolean translucent = mAttrs.alpha == 0.0f;
return shown && !exiting && !translucent;
}
@@ -2031,6 +2059,11 @@
if (dc == null) {
return;
}
+
+ // If layout is currently deferred, we want to hold of with updating the layers.
+ if (mService.mWindowPlacerLocked.isLayoutDeferred()) {
+ return;
+ }
final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
if (dimLayerUser != null && dc.mDimLayerController.isDimming(dimLayerUser, mWinAnimator)) {
// Force an animation pass just to update the mDimLayer layer.
@@ -2043,7 +2076,7 @@
super(inputChannel, mService.mH.getLooper());
}
@Override
- public void onInputEvent(InputEvent event) {
+ public void onInputEvent(InputEvent event, int displayId) {
finishInputEvent(event, true);
}
}
@@ -3228,6 +3261,15 @@
return !isInMultiWindowMode();
}
+ /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+ boolean isLetterboxedAppWindow() {
+ final Task task = getTask();
+ final boolean taskIsFullscreen = task != null && task.isFullscreen();
+ final boolean appWindowIsFullscreen = mAppToken != null && !mAppToken.hasBounds();
+
+ return taskIsFullscreen && !appWindowIsFullscreen;
+ }
+
/** Returns the appropriate bounds to use for computing frames. */
private void getContainerBounds(Rect outBounds) {
if (isInMultiWindowMode()) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 23b515e..86265c29 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,6 +20,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -631,6 +632,10 @@
return mSurfaceController;
}
+ if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
+ windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
+ }
+
w.setHasSurface(false);
if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
@@ -1195,7 +1200,8 @@
if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
+ w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
- final boolean fullscreen = w.fillsDisplay();
+ final Task task = w.getTask();
+ final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
final boolean isFreeformResizing =
w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
@@ -1521,6 +1527,19 @@
}
}
+ /**
+ * Get rect of the task this window is currently in. If there is no task, rect will be set to
+ * empty.
+ */
+ void getContainerRect(Rect rect) {
+ final Task task = mWin.getTask();
+ if (task != null) {
+ task.getDimBounds(rect);
+ } else {
+ rect.left = rect.top = rect.right = rect.bottom = 0;
+ }
+ }
+
void prepareSurfaceLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
if (!hasSurface()) {
@@ -1627,9 +1646,14 @@
// hidden while the screen is turning off.
// TODO(b/63773439): These cases should be eliminated, though we probably still
// want to process mTurnOnScreen in this way for clarity.
- if (mWin.mTurnOnScreen) {
+ if (mWin.mTurnOnScreen && mWin.mAppToken.canTurnScreenOn()) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
mWin.mTurnOnScreen = false;
+
+ // The window should only turn the screen on once per resume, but
+ // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to
+ // false so the window doesn't turn the screen on again during this resume.
+ mWin.mAppToken.setCanTurnScreenOn(false);
mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 1728cfb..110d5cb 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -50,7 +50,7 @@
final WindowStateAnimator mAnimator;
- private SurfaceControl mSurfaceControl;
+ private SurfaceControlWithBackground mSurfaceControl;
// Should only be set from within setShown().
private boolean mSurfaceShown = false;
@@ -97,15 +97,10 @@
mWindowType = windowType;
mWindowSession = win.mSession;
- if (DEBUG_SURFACE_TRACE) {
- mSurfaceControl = new SurfaceTrace(
- s, name, w, h, format, flags, windowType, ownerUid);
- } else {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
- mSurfaceControl = new SurfaceControl(
- s, name, w, h, format, flags, windowType, ownerUid);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
+ mSurfaceControl = new SurfaceControlWithBackground(
+ s, name, w, h, format, flags, windowType, ownerUid, this);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (mService.mRoot.mSurfaceTraceEnabled) {
mSurfaceControl = new RemoteSurfaceTrace(
@@ -118,7 +113,7 @@
}
void removeRemoteTrace() {
- mSurfaceControl = new SurfaceControl(mSurfaceControl);
+ mSurfaceControl = new SurfaceControlWithBackground(mSurfaceControl);
}
@@ -291,30 +286,30 @@
mSurfaceControl.setGeometryAppliesWithResize();
}
- void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
+ void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
boolean recoveringMemory) {
final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
- mLastDsdy != dsdy || mLastDtdy != dtdy;
+ mLastDtdy != dtdy || mLastDsdy != dsdy;
if (!matrixChanged) {
return;
}
mLastDsdx = dsdx;
mLastDtdx = dtdx;
- mLastDsdy = dsdy;
mLastDtdy = dtdy;
+ mLastDsdy = dsdy;
try {
if (SHOW_TRANSACTIONS) logSurface(
- "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+ "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
mSurfaceControl.setMatrix(
- dsdx, dtdx, dsdy, dtdy);
+ dsdx, dtdx, dtdy, dsdy);
} catch (RuntimeException e) {
// If something goes wrong with the surface (such
// as running out of memory), don't take down the
// entire system.
Slog.e(TAG, "Error setting matrix on surface surface" + title
- + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+ + " MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
if (!recoveringMemory) {
mAnimator.reclaimSomeSurfaceMemory("matrix", true);
}
@@ -421,6 +416,10 @@
}
}
+ void getContainerRect(Rect rect) {
+ mAnimator.getContainerRect(rect);
+ }
+
boolean showRobustlyInTransaction() {
if (SHOW_TRANSACTIONS) logSurface(
"SHOW (performLayout)", null);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 6909892..581b044 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -127,6 +127,10 @@
}
}
+ boolean isLayoutDeferred() {
+ return mDeferDepth > 0;
+ }
+
final void performSurfacePlacement() {
performSurfacePlacement(false /* force */);
}
diff --git a/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp b/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
index 492be17..b3817db 100644
--- a/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
+++ b/services/core/jni/BroadcastRadio/BroadcastRadioService.cpp
@@ -27,14 +27,17 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <core_jni_helpers.h>
#include <hidl/ServiceManagement.h>
+#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>
-#include <JNIHelp.h>
namespace android {
namespace server {
namespace BroadcastRadio {
namespace BroadcastRadioService {
+using std::lock_guard;
+using std::mutex;
+
using hardware::Return;
using hardware::hidl_string;
using hardware::hidl_vec;
@@ -50,7 +53,7 @@
using V1_0::MetaData;
using V1_0::ITuner;
-static Mutex gContextMutex;
+static mutex gContextMutex;
static struct {
struct {
@@ -90,8 +93,8 @@
}
static jlong nativeInit(JNIEnv *env, jobject obj) {
- ALOGV("nativeInit()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto nativeContext = new ServiceContext();
static_assert(sizeof(jlong) >= sizeof(nativeContext), "jlong is smaller than a pointer");
@@ -99,16 +102,16 @@
}
static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeFinalize()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto ctx = reinterpret_cast<ServiceContext*>(nativeContext);
delete ctx;
}
static jobject nativeLoadModules(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeLoadModules()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
// Get list of registered HIDL HAL implementations.
@@ -182,8 +185,8 @@
static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jint moduleId,
jobject bandConfig, bool withAudio, jobject callback) {
- ALOGV("nativeOpenTuner()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
if (callback == nullptr) {
diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
index 0c84e6d..85ec9e0 100644
--- a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
+++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp
@@ -23,45 +23,38 @@
namespace android {
-NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mExitting(false), mvm(vm) {
- auto res = pthread_create(&mThread, nullptr, main, this);
- if (res != 0) {
- ALOGE("Couldn't start NativeCallbackThread");
- mThread = 0;
- return;
- }
+using std::lock_guard;
+using std::mutex;
+using std::unique_lock;
+
+NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mvm(vm), mExiting(false),
+ mThread(&NativeCallbackThread::threadLoop, this) {
ALOGD("Started native callback thread %p", this);
}
NativeCallbackThread::~NativeCallbackThread() {
- ALOGV("~NativeCallbackThread %p", this);
+ ALOGV("%s %p", __func__, this);
stop();
}
-void* NativeCallbackThread::main(void *args) {
- auto self = reinterpret_cast<NativeCallbackThread*>(args);
- self->main();
- return nullptr;
-}
-
-void NativeCallbackThread::main() {
- ALOGV("NativeCallbackThread::main()");
+void NativeCallbackThread::threadLoop() {
+ ALOGV("%s", __func__);
JNIEnv *env = nullptr;
JavaVMAttachArgs aargs = {JNI_VERSION_1_4, "NativeCallbackThread", nullptr};
if (mvm->AttachCurrentThread(&env, &aargs) != JNI_OK || env == nullptr) {
ALOGE("Couldn't attach thread");
+ mExiting = true;
return;
}
- while (!mExitting) {
+ while (!mExiting) {
ALOGV("Waiting for task...");
Task task;
{
- AutoMutex _l(mQueueMutex);
- auto res = mQueueCond.wait(mQueueMutex);
- ALOGE_IF(res != 0, "Wait failed: %d", res);
- if (mExitting || res != 0) break;
+ unique_lock<mutex> lk(mQueueMutex);
+ mQueueCond.wait(lk);
+ if (mExiting) break;
if (mQueue.empty()) continue;
task = mQueue.front();
@@ -84,36 +77,35 @@
}
void NativeCallbackThread::enqueue(const Task &task) {
- AutoMutex _l(mQueueMutex);
+ lock_guard<mutex> lk(mQueueMutex);
- if (mThread == 0 || mExitting) {
+ if (mExiting) {
ALOGW("Callback thread %p is not serving calls", this);
return;
}
mQueue.push(task);
- mQueueCond.signal();
+ mQueueCond.notify_one();
}
void NativeCallbackThread::stop() {
- ALOGV("stop() %p", this);
+ ALOGV("%s %p", __func__, this);
{
- AutoMutex _l(mQueueMutex);
+ lock_guard<mutex> lk(mQueueMutex);
- if (mThread == 0 || mExitting) return;
+ if (mExiting) return;
- mExitting = true;
- mQueueCond.signal();
+ mExiting = true;
+ mQueueCond.notify_one();
}
- if (pthread_self() == mThread) {
+ if (mThread.get_id() == std::thread::id()) {
// you can't self-join a thread, but it's ok when calling from our sub-task
ALOGD("About to stop native callback thread %p", this);
+ mThread.detach();
} else {
- auto ret = pthread_join(mThread, nullptr);
- ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
-
+ mThread.join();
ALOGD("Stopped native callback thread %p", this);
}
}
diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.h b/services/core/jni/BroadcastRadio/NativeCallbackThread.h
index 4e03b11..53990be 100644
--- a/services/core/jni/BroadcastRadio/NativeCallbackThread.h
+++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.h
@@ -20,26 +20,23 @@
#include <android-base/macros.h>
#include <functional>
#include <jni.h>
-#include <pthread.h>
#include <queue>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
+#include <thread>
namespace android {
class NativeCallbackThread {
typedef std::function<void(JNIEnv*)> Task;
- pthread_t mThread;
- Mutex mQueueMutex;
- Condition mQueueCond;
- std::atomic<bool> mExitting;
-
JavaVM *mvm;
std::queue<Task> mQueue;
- static void* main(void *args);
- void main();
+ std::mutex mQueueMutex;
+ std::condition_variable mQueueCond;
+ std::atomic<bool> mExiting;
+ std::thread mThread;
+
+ void threadLoop();
DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread);
diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp
index 2e8798b..85603d5 100644
--- a/services/core/jni/BroadcastRadio/Tuner.cpp
+++ b/services/core/jni/BroadcastRadio/Tuner.cpp
@@ -22,12 +22,12 @@
#include "convert.h"
#include "TunerCallback.h"
-#include <JNIHelp.h>
-#include <Utils.h>
#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
#include <binder/IPCThreadState.h>
+#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
#include <media/AudioSystem.h>
+#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>
namespace android {
@@ -35,6 +35,9 @@
namespace BroadcastRadio {
namespace Tuner {
+using std::lock_guard;
+using std::mutex;
+
using hardware::Return;
using hardware::hidl_death_recipient;
using hardware::hidl_vec;
@@ -49,7 +52,7 @@
using V1_1::ITunerCallback;
using V1_1::ProgramListResult;
-static Mutex gContextMutex;
+static mutex gContextMutex;
static struct {
struct {
@@ -106,8 +109,8 @@
}
static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev, bool withAudio, jint band) {
- ALOGV("nativeInit()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto ctx = new TunerContext();
ctx->mHalRev = static_cast<HalRevision>(halRev);
@@ -119,8 +122,8 @@
}
static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeFinalize()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto ctx = reinterpret_cast<TunerContext*>(nativeContext);
delete ctx;
@@ -150,10 +153,9 @@
void assignHalInterfaces(JNIEnv *env, JavaRef<jobject> const &jTuner,
sp<V1_0::IBroadcastRadio> halModule, sp<V1_0::ITuner> halTuner) {
- ALOGV("setHalTuner(%p)", halTuner.get());
+ ALOGV("%s(%p)", __func__, halTuner.get());
ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
-
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(env, jTuner);
if (ctx.mIsClosed) {
@@ -187,12 +189,12 @@
}
sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
return getHalTuner(getNativeContext(nativeContext));
}
sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
return getNativeContext(nativeContext).mHalTuner11;
}
@@ -206,8 +208,9 @@
}
static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
+
if (ctx.mIsClosed) return;
ctx.mIsClosed = true;
@@ -228,9 +231,10 @@
}
static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
- ALOGV("nativeSetConfiguration()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
+
auto halTuner = getHalTuner(ctx);
if (halTuner == nullptr) return;
@@ -244,7 +248,7 @@
static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
Region region) {
- ALOGV("nativeSetConfiguration()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner(nativeContext);
if (halTuner == nullptr) return nullptr;
@@ -263,7 +267,7 @@
static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
bool directionDown, bool skipSubChannel) {
- ALOGV("nativeStep()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner(nativeContext);
if (halTuner == nullptr) return;
@@ -273,7 +277,7 @@
static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
bool directionDown, bool skipSubChannel) {
- ALOGV("nativeScan()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner(nativeContext);
if (halTuner == nullptr) return;
@@ -282,16 +286,17 @@
}
static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext, jobject jSelector) {
- ALOGV("nativeTune()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
+
auto halTuner10 = getHalTuner(ctx);
auto halTuner11 = ctx.mHalTuner11;
if (halTuner10 == nullptr) return;
auto selector = convert::ProgramSelectorToHal(env, jSelector);
if (halTuner11 != nullptr) {
- convert::ThrowIfFailed(env, halTuner11->tune_1_1(selector));
+ convert::ThrowIfFailed(env, halTuner11->tuneByProgramSelector(selector));
} else {
uint32_t channel, subChannel;
if (!V1_1::utils::getLegacyChannel(selector, &channel, &subChannel)) {
@@ -304,7 +309,7 @@
}
static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeCancel()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner(nativeContext);
if (halTuner == nullptr) return;
@@ -323,9 +328,10 @@
}
static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeGetProgramInformation()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
+
auto halTuner10 = getHalTuner(ctx);
auto halTuner11 = ctx.mHalTuner11;
if (halTuner10 == nullptr) return nullptr;
@@ -355,7 +361,7 @@
}
static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeStartBackgroundScan()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner11(nativeContext);
if (halTuner == nullptr) {
ALOGI("Background scan is not supported with HAL < 1.1");
@@ -368,8 +374,8 @@
return !convert::ThrowIfFailed(env, halResult);
}
-static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
- ALOGV("nativeGetProgramList()");
+static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jobject jVendorFilter) {
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner11(nativeContext);
if (halTuner == nullptr) {
ALOGI("Program list is not supported with HAL < 1.1");
@@ -378,7 +384,7 @@
JavaRef<jobject> jList;
ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED;
- auto filter = env->GetStringUTFChars(jFilter, nullptr);
+ auto filter = convert::VendorInfoToHal(env, jVendorFilter);
auto hidlResult = halTuner->getProgramList(filter,
[&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) {
halResult = result;
@@ -398,7 +404,7 @@
static jbyteArray nativeGetImage(JNIEnv *env, jobject obj, jlong nativeContext, jint id) {
ALOGV("%s(%x)", __func__, id);
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
if (ctx.mHalModule11 == nullptr) {
@@ -435,7 +441,7 @@
}
static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeIsAnalogForced()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner11(nativeContext);
if (halTuner == nullptr) {
jniThrowException(env, "java/lang/IllegalStateException",
@@ -456,7 +462,7 @@
}
static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
- ALOGV("nativeSetAnalogForced()");
+ ALOGV("%s(%d)", __func__, isForced);
auto halTuner = getHalTuner11(nativeContext);
if (halTuner == nullptr) {
jniThrowException(env, "java/lang/IllegalStateException",
@@ -469,7 +475,7 @@
}
static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeIsAntennaConnected()");
+ ALOGV("%s", __func__);
auto halTuner = getHalTuner(nativeContext);
if (halTuner == nullptr) return false;
@@ -499,7 +505,7 @@
{ "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
(void*)nativeGetProgramInformation },
{ "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan },
- { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;",
+ { "nativeGetProgramList", "(JLjava/util/Map;)Ljava/util/List;",
(void*)nativeGetProgramList },
{ "nativeGetImage", "(JI)[B", (void*)nativeGetImage},
{ "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
diff --git a/services/core/jni/BroadcastRadio/TunerCallback.cpp b/services/core/jni/BroadcastRadio/TunerCallback.cpp
index d22ee82..d53721f 100644
--- a/services/core/jni/BroadcastRadio/TunerCallback.cpp
+++ b/services/core/jni/BroadcastRadio/TunerCallback.cpp
@@ -22,9 +22,9 @@
#include "Tuner.h"
#include "convert.h"
-#include <JNIHelp.h>
-#include <Utils.h>
+#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
+#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>
namespace android {
@@ -32,6 +32,9 @@
namespace BroadcastRadio {
namespace TunerCallback {
+using std::lock_guard;
+using std::mutex;
+
using hardware::Return;
using hardware::hidl_vec;
@@ -43,6 +46,7 @@
using V1_0::MetaData;
using V1_0::Result;
using V1_1::ITunerCallback;
+using V1_1::ProgramInfo;
using V1_1::ProgramListResult;
using V1_1::ProgramSelector;
@@ -55,7 +59,7 @@
jmethodID handleHwFailure;
jmethodID onError;
jmethodID onConfigurationChanged;
- jmethodID onProgramInfoChanged;
+ jmethodID onCurrentProgramInfoChanged;
jmethodID onTrafficAnnouncement;
jmethodID onEmergencyAnnouncement;
jmethodID onAntennaState;
@@ -76,9 +80,11 @@
BACKGROUND_SCAN_FAILED = 6,
};
-static Mutex gContextMutex;
+static mutex gContextMutex;
class NativeCallback : public ITunerCallback {
+ mutex mMut;
+
jobject mJTuner;
jobject mJCallback;
NativeCallbackThread mCallbackThread;
@@ -86,6 +92,9 @@
Band mBand;
+ // Carries current program info data for 1.0 newMetadata callback.
+ V1_0::ProgramInfo mCurrentProgramInfo;
+
DISALLOW_COPY_AND_ASSIGN(NativeCallback);
public:
@@ -104,11 +113,10 @@
virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata);
virtual Return<void> tuneComplete_1_1(Result result, const ProgramSelector& selector);
- virtual Return<void> afSwitch_1_1(const ProgramSelector& selector);
virtual Return<void> backgroundScanAvailable(bool isAvailable);
virtual Return<void> backgroundScanComplete(ProgramListResult result);
virtual Return<void> programListChanged();
- virtual Return<void> programInfoChanged();
+ virtual Return<void> currentProgramInfoChanged(const ProgramInfo& info);
};
struct TunerCallbackContext {
@@ -122,13 +130,13 @@
NativeCallback::NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev)
: mCallbackThread(gvm), mHalRev(halRev) {
- ALOGV("NativeCallback()");
+ ALOGV("%s", __func__);
mJTuner = env->NewGlobalRef(jTuner);
mJCallback = env->NewGlobalRef(jCallback);
}
NativeCallback::~NativeCallback() {
- ALOGV("~NativeCallback()");
+ ALOGV("%s", __func__);
// stop callback thread before dereferencing client callback
mCallbackThread.stop();
@@ -155,7 +163,7 @@
}
Return<void> NativeCallback::configChange(Result result, const BandConfig& config) {
- ALOGV("configChange(%d)", result);
+ ALOGV("%s(%d)", __func__, result);
mCallbackThread.enqueue([result, config, this](JNIEnv *env) {
if (result == Result::OK) {
@@ -173,11 +181,26 @@
}
Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
- ALOGV("tuneComplete(%d)", result);
+ ALOGV("%s(%d)", __func__, result);
if (mHalRev > HalRevision::V1_0) {
ALOGW("1.0 callback was ignored");
- return Return<void>();
+ return {};
+ }
+
+ if (result == Result::OK) {
+ {
+ lock_guard<mutex> lk(mMut);
+ mCurrentProgramInfo = info;
+ }
+
+ // tuneComplete_1_1 implementation does not handle success case, see the implementation
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info, mBand);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
+ });
+ return {};
}
auto selector = V1_1::utils::make_selector(mBand, info.channel, info.subChannel);
@@ -185,33 +208,29 @@
}
Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelector& selector) {
- ALOGV("tuneComplete_1_1(%d)", result);
+ ALOGV("%s(%d)", __func__, result);
mCallbackThread.enqueue([result, this](JNIEnv *env) {
- if (result == Result::OK) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
- } else {
- TunerError cause = TunerError::CANCELLED;
- if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
- }
+ /* for HAL 1.1, onCurrentProgramInfoChanged will be called from currentProgramInfoChanged,
+ * so we don't need to handle success case here.
+ */
+ if (result == Result::OK) return;
+
+ TunerError cause = TunerError::CANCELLED;
+ if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
});
return Return<void>();
}
Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
- ALOGV("afSwitch()");
+ ALOGV("%s", __func__);
return tuneComplete(Result::OK, info);
}
-Return<void> NativeCallback::afSwitch_1_1(const ProgramSelector& selector) {
- ALOGV("afSwitch_1_1()");
- return tuneComplete_1_1(Result::OK, selector);
-}
-
Return<void> NativeCallback::antennaStateChange(bool connected) {
- ALOGV("antennaStateChange(%d)", connected);
+ ALOGV("%s(%d)", __func__, connected);
mCallbackThread.enqueue([this, connected](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onAntennaState, connected);
@@ -221,7 +240,7 @@
}
Return<void> NativeCallback::trafficAnnouncement(bool active) {
- ALOGV("trafficAnnouncement(%d)", active);
+ ALOGV("%s(%d)", __func__, active);
mCallbackThread.enqueue([this, active](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onTrafficAnnouncement, active);
@@ -231,7 +250,7 @@
}
Return<void> NativeCallback::emergencyAnnouncement(bool active) {
- ALOGV("emergencyAnnouncement(%d)", active);
+ ALOGV("%s(%d)", __func__, active);
mCallbackThread.enqueue([this, active](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onEmergencyAnnouncement, active);
@@ -242,23 +261,36 @@
Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
const hidl_vec<MetaData>& metadata) {
- // channel and subChannel are not used
- ALOGV("newMetadata(%d, %d)", channel, subChannel);
+ ALOGV("%s(%d, %d)", __func__, channel, subChannel);
if (mHalRev > HalRevision::V1_0) {
ALOGW("1.0 callback was ignored");
- return Return<void>();
+ return {};
}
- mCallbackThread.enqueue([this, metadata](JNIEnv *env) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
+ V1_0::ProgramInfo info;
+ {
+ lock_guard<mutex> lk(mMut);
+ info = mCurrentProgramInfo;
+ }
+ if (channel != info.channel || subChannel != info.subChannel) {
+ ALOGE("Channel mismatch on newMetadata callback (%d.%d != %d.%d)",
+ channel, subChannel, info.channel, info.subChannel);
+ return {};
+ }
+ info.metadata = metadata;
+
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info, mBand);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
});
- return Return<void>();
+ return {};
}
Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
- ALOGV("backgroundScanAvailable(%d)", isAvailable);
+ ALOGV("%s(%d)", __func__, isAvailable);
mCallbackThread.enqueue([this, isAvailable](JNIEnv *env) {
env->CallVoidMethod(mJCallback,
@@ -269,7 +301,7 @@
}
Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
- ALOGV("backgroundScanComplete(%d)", result);
+ ALOGV("%s(%d)", __func__, result);
mCallbackThread.enqueue([this, result](JNIEnv *env) {
if (result == ProgramListResult::OK) {
@@ -285,7 +317,7 @@
}
Return<void> NativeCallback::programListChanged() {
- ALOGV("programListChanged()");
+ ALOGV("%s", __func__);
mCallbackThread.enqueue([this](JNIEnv *env) {
env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramListChanged);
@@ -294,11 +326,13 @@
return Return<void>();
}
-Return<void> NativeCallback::programInfoChanged() {
- ALOGV("programInfoChanged()");
+Return<void> NativeCallback::currentProgramInfoChanged(const ProgramInfo& info) {
+ ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());
- mCallbackThread.enqueue([this](JNIEnv *env) {
- env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
+ mCallbackThread.enqueue([this, info](JNIEnv *env) {
+ auto jInfo = convert::ProgramInfoFromHal(env, info);
+ env->CallVoidMethod(mJCallback, gjni.TunerCallback.onCurrentProgramInfoChanged,
+ jInfo.get());
});
return Return<void>();
@@ -318,8 +352,8 @@
}
static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev) {
- ALOGV("nativeInit()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto halRev = static_cast<HalRevision>(jHalRev);
@@ -331,16 +365,16 @@
}
static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeFinalize()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto ctx = reinterpret_cast<TunerCallbackContext*>(nativeContext);
delete ctx;
}
static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
- ALOGV("nativeDetach()");
- AutoMutex _l(gContextMutex);
+ ALOGV("%s", __func__);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(nativeContext);
if (ctx.mNativeCallback == nullptr) return;
@@ -349,7 +383,7 @@
}
sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject jTunerCallback) {
- AutoMutex _l(gContextMutex);
+ lock_guard<mutex> lk(gContextMutex);
auto& ctx = getNativeContext(env, jTunerCallback);
return ctx.mNativeCallback;
}
@@ -376,8 +410,8 @@
gjni.TunerCallback.onError = GetMethodIDOrDie(env, tunerCbClass, "onError", "(I)V");
gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass,
"onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
- gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
- "onProgramInfoChanged", "()V");
+ gjni.TunerCallback.onCurrentProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
+ "onCurrentProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
gjni.TunerCallback.onTrafficAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
"onTrafficAnnouncement", "(Z)V");
gjni.TunerCallback.onEmergencyAnnouncement = GetMethodIDOrDie(env, tunerCbClass,
diff --git a/services/core/jni/BroadcastRadio/convert.cpp b/services/core/jni/BroadcastRadio/convert.cpp
index a2e5643..3e0bc63 100644
--- a/services/core/jni/BroadcastRadio/convert.cpp
+++ b/services/core/jni/BroadcastRadio/convert.cpp
@@ -19,9 +19,9 @@
#include "convert.h"
-#include <JNIHelp.h>
-#include <Utils.h>
+#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
+#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>
namespace android {
@@ -41,6 +41,7 @@
using V1_1::ProgramIdentifier;
using V1_1::ProgramListResult;
using V1_1::ProgramSelector;
+using V1_1::VendorKeyValue;
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
@@ -82,6 +83,20 @@
struct {
jclass clazz;
+ jmethodID stringMapToNative;
+ } Convert;
+
+ struct {
+ jclass clazz;
+ jmethodID cstor;
+ } HashMap;
+
+ struct {
+ jmethodID put;
+ } Map;
+
+ struct {
+ jclass clazz;
jmethodID cstor;
} ModuleProperties;
@@ -228,6 +243,53 @@
std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter));
}
+static std::string StringFromJava(JNIEnv *env, JavaRef<jstring> &jStr) {
+ auto cstr = (jStr == nullptr) ? nullptr : env->GetStringUTFChars(jStr.get(), nullptr);
+ std::string str(cstr);
+ env->ReleaseStringUTFChars(jStr.get(), cstr);
+ return str;
+}
+
+JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hidl_vec<VendorKeyValue> &info) {
+ ALOGV("%s(%s)", __func__, toString(info).substr(0, 100).c_str());
+
+ auto jInfo = make_javaref(env, env->NewObject(gjni.HashMap.clazz, gjni.HashMap.cstor));
+
+ for (auto&& entry : info) {
+ auto jKey = make_javastr(env, entry.key);
+ auto jValue = make_javastr(env, entry.value);
+ env->CallObjectMethod(jInfo.get(), gjni.Map.put, jKey.get(), jValue.get());
+ }
+
+ return jInfo;
+}
+
+hidl_vec<VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo) {
+ ALOGV("%s", __func__);
+
+ auto jInfoArr = make_javaref(env, static_cast<jobjectArray>(env->CallStaticObjectMethod(
+ gjni.Convert.clazz, gjni.Convert.stringMapToNative, jInfo)));
+ LOG_FATAL_IF(jInfoArr == nullptr, "Converted array is null");
+
+ auto len = env->GetArrayLength(jInfoArr.get());
+ hidl_vec<VendorKeyValue> vec;
+ vec.resize(len);
+
+ for (jsize i = 0; i < len; i++) {
+ auto entry = make_javaref(env, static_cast<jobjectArray>(
+ env->GetObjectArrayElement(jInfoArr.get(), i)));
+ auto jKey = make_javaref(env, static_cast<jstring>(
+ env->GetObjectArrayElement(entry.get(), 0)));
+ auto jValue = make_javaref(env, static_cast<jstring>(
+ env->GetObjectArrayElement(entry.get(), 1)));
+ auto key = StringFromJava(env, jKey);
+ auto value = StringFromJava(env, jValue);
+ vec[i] = { key, value };
+ }
+
+ return vec;
+}
+
static Rds RdsForRegion(bool rds, Region region) {
if (!rds) return Rds::NONE;
@@ -262,7 +324,7 @@
static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10,
const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) {
- ALOGV("ModulePropertiesFromHal()");
+ ALOGV("%s", __func__);
using namespace std::placeholders;
auto jServiceName = make_javastr(env, serviceName);
@@ -271,7 +333,7 @@
auto jVersion = make_javastr(env, prop10.version);
auto jSerial = make_javastr(env, prop10.serial);
bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false;
- auto jVendorInfo = prop11 ? make_javastr(env, prop11->vendorInfo) : nullptr;
+ auto jVendorInfo = prop11 ? VendorInfoFromHal(env, prop11->vendorInfo) : nullptr;
// ITU_1 is the default region just because its index is 0.
auto jBands = ArrayFromHal<V1_0::BandConfig>(env, prop10.bands, gjni.BandDescriptor.clazz,
std::bind(BandDescriptorFromHal, _1, _2, Region::ITU_1));
@@ -298,7 +360,7 @@
}
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
- ALOGV("BandDescriptorFromHal()");
+ ALOGV("%s", __func__);
jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
@@ -327,7 +389,7 @@
}
JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
- ALOGV("BandConfigFromHal()");
+ ALOGV("%s", __func__);
auto descriptor = BandDescriptorFromHal(env, config, region);
if (descriptor == nullptr) return nullptr;
@@ -350,7 +412,7 @@
}
V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region ®ion) {
- ALOGV("BandConfigToHal()");
+ ALOGV("%s", __func__);
auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
if (jDescriptor == nullptr) {
ALOGE("Descriptor is missing");
@@ -392,7 +454,7 @@
}
JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> &metadata) {
- ALOGV("MetadataFromHal()");
+ ALOGV("%s", __func__);
if (metadata.size() == 0) return nullptr;
auto jMetadata = make_javaref(env, env->NewObject(
@@ -445,13 +507,13 @@
}
static JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdentifier &id) {
- ALOGV("ProgramIdentifierFromHal()");
+ ALOGV("%s", __func__);
return make_javaref(env, env->NewObject(gjni.ProgramSelector.Identifier.clazz,
gjni.ProgramSelector.Identifier.cstor, id.type, id.value));
}
static JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) {
- ALOGV("ProgramSelectorFromHal()");
+ ALOGV("%s", __func__);
auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId);
auto jSecondary = ArrayFromHal(env, selector.secondaryIds,
gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal);
@@ -462,7 +524,7 @@
}
static ProgramIdentifier ProgramIdentifierToHal(JNIEnv *env, jobject jId) {
- ALOGV("ProgramIdentifierToHal()");
+ ALOGV("%s", __func__);
ProgramIdentifier id = {};
id.type = env->GetIntField(jId, gjni.ProgramSelector.Identifier.type);
@@ -471,7 +533,7 @@
}
ProgramSelector ProgramSelectorToHal(JNIEnv *env, jobject jSelector) {
- ALOGV("ProgramSelectorToHal()");
+ ALOGV("%s", __func__);
ProgramSelector selector = {};
@@ -509,10 +571,10 @@
static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
const V1_1::ProgramInfo *info11, const ProgramSelector &selector) {
- ALOGV("ProgramInfoFromHal()");
+ ALOGV("%s", __func__);
auto jMetadata = MetadataFromHal(env, info10.metadata);
- auto jVendorInfo = info11 ? make_javastr(env, info11->vendorInfo) : nullptr;
+ auto jVendorInfo = info11 ? VendorInfoFromHal(env, info11->vendorInfo) : nullptr;
auto jSelector = ProgramSelectorFromHal(env, selector);
return make_javaref(env, env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor,
@@ -579,19 +641,32 @@
gjni.AmBandDescriptor.cstor = GetMethodIDOrDie(env, amBandDescriptorClass,
"<init>", "(IIIIIZ)V");
+ auto convertClass = FindClassOrDie(env, "com/android/server/broadcastradio/Convert");
+ gjni.Convert.clazz = MakeGlobalRefOrDie(env, convertClass);
+ gjni.Convert.stringMapToNative = GetStaticMethodIDOrDie(env, convertClass, "stringMapToNative",
+ "(Ljava/util/Map;)[[Ljava/lang/String;");
+
+ auto hashMapClass = FindClassOrDie(env, "java/util/HashMap");
+ gjni.HashMap.clazz = MakeGlobalRefOrDie(env, hashMapClass);
+ gjni.HashMap.cstor = GetMethodIDOrDie(env, hashMapClass, "<init>", "()V");
+
+ auto mapClass = FindClassOrDie(env, "java/util/Map");
+ gjni.Map.put = GetMethodIDOrDie(env, mapClass, "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
auto modulePropertiesClass = FindClassOrDie(env,
"android/hardware/radio/RadioManager$ModuleProperties");
gjni.ModuleProperties.clazz = MakeGlobalRefOrDie(env, modulePropertiesClass);
gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
"(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z"
- "[I[ILjava/lang/String;)V");
+ "[I[ILjava/util/Map;)V");
auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
"(Landroid/hardware/radio/ProgramSelector;ZZZILandroid/hardware/radio/RadioMetadata;I"
- "Ljava/lang/String;)V");
+ "Ljava/util/Map;)V");
auto programSelectorClass = FindClassOrDie(env, "android/hardware/radio/ProgramSelector");
gjni.ProgramSelector.clazz = MakeGlobalRefOrDie(env, programSelectorClass);
diff --git a/services/core/jni/BroadcastRadio/convert.h b/services/core/jni/BroadcastRadio/convert.h
index 198e594..1fc75f0 100644
--- a/services/core/jni/BroadcastRadio/convert.h
+++ b/services/core/jni/BroadcastRadio/convert.h
@@ -35,6 +35,9 @@
namespace V1_0 = hardware::broadcastradio::V1_0;
namespace V1_1 = hardware::broadcastradio::V1_1;
+JavaRef<jobject> VendorInfoFromHal(JNIEnv *env, const hardware::hidl_vec<V1_1::VendorKeyValue> &info);
+hardware::hidl_vec<V1_1::VendorKeyValue> VendorInfoToHal(JNIEnv *env, jobject jInfo);
+
JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties,
jint moduleId, const std::string& serviceName);
JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_1::Properties &properties,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3757b7d..a1b9099 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -34,6 +34,7 @@
import android.os.FileUtils;
import android.os.IIncidentManager;
import android.os.Looper;
+import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -463,7 +464,20 @@
}
}
}
- ShutdownThread.rebootOrShutdown(null, reboot, reason);
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (this) {
+ ShutdownThread.rebootOrShutdown(null, reboot, reason);
+ }
+ }
+ };
+
+ // ShutdownThread must run on a looper capable of displaying the UI.
+ Message msg = Message.obtain(UiThread.getHandler(), runnable);
+ msg.setAsynchronous(true);
+ UiThread.getHandler().sendMessage(msg);
+
}
}
@@ -1194,11 +1208,16 @@
traceEnd();
}
- if (!disableNonCoreServices && context.getResources().getBoolean(
- R.bool.config_enableUpdateableTimeZoneRules)) {
+ // timezone.RulesManagerService will prevent a device starting up if the chain of trust
+ // required for safe time zone updates might be broken. RuleManagerService cannot do
+ // this check when mOnlyCore == true, so we don't enable the service in this case.
+ final boolean startRulesManagerService =
+ !mOnlyCore && context.getResources().getBoolean(
+ R.bool.config_enableUpdateableTimeZoneRules);
+ if (startRulesManagerService) {
traceBeginAndSlog("StartTimeZoneRulesManagerService");
mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceEnd();
}
traceBeginAndSlog("StartAudioService");
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 6c417a9..5121c29 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -736,14 +736,18 @@
UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false,
false /* enforceUserUnlockingOrUnlocked */);
+ boolean prunePrintServices = false;
synchronized (mLock) {
if (hadPrintService(userState, packageName)
|| hasPrintService(packageName)) {
userState.updateIfNeededLocked();
+ prunePrintServices = true;
}
}
- userState.prunePrintServices();
+ if (prunePrintServices) {
+ userState.prunePrintServices();
+ }
}
@Override
@@ -752,13 +756,17 @@
UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false,
false /* enforceUserUnlockingOrUnlocked */);
+ boolean prunePrintServices = false;
synchronized (mLock) {
if (hadPrintService(userState, packageName)) {
userState.updateIfNeededLocked();
+ prunePrintServices = true;
}
}
- userState.prunePrintServices();
+ if (prunePrintServices) {
+ userState.prunePrintServices();
+ }
}
@Override
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 5e71a45..09af1e2 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -333,6 +333,42 @@
}
@Test
+ public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
+ throws Exception {
+ final NotificationChannel channel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+ mBinderService.createNotificationChannels(PKG,
+ new ParceledListSlice(Arrays.asList(channel)));
+
+ // Recreating the channel doesn't throw, but ignores importance.
+ final NotificationChannel dupeChannel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);
+ mBinderService.createNotificationChannels(PKG,
+ new ParceledListSlice(Arrays.asList(dupeChannel)));
+ final NotificationChannel createdChannel =
+ mBinderService.getNotificationChannel(PKG, "id");
+ assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
+ }
+
+ @Test
+ public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
+ throws Exception {
+ final NotificationChannel channel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+ mBinderService.createNotificationChannels(PKG,
+ new ParceledListSlice(Arrays.asList(channel)));
+
+ // Recreating with a lower importance is allowed to modify the channel.
+ final NotificationChannel dupeChannel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
+ mBinderService.createNotificationChannels(PKG,
+ new ParceledListSlice(Arrays.asList(dupeChannel)));
+ final NotificationChannel createdChannel =
+ mBinderService.getNotificationChannel(PKG, "id");
+ assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
+ }
+
+ @Test
public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
throws Exception {
final NotificationChannel channel =
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index ceb92de..82ff0d8 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -31,6 +31,7 @@
import static org.mockito.Mockito.when;
import android.Manifest.permission;
+import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -61,15 +62,18 @@
@RunWith(AndroidJUnit4.class)
public class NetworkScorerAppManagerTest {
+ private static final int PACKAGE_UID = 924;
private static String MOCK_SERVICE_LABEL = "Mock Service";
private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override";
private static String MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID =
"Mock Network Available Notification Channel Id";
+ private static final ComponentName RECO_COMPONENT = new ComponentName("package1", "class1");
@Mock private Context mMockContext;
@Mock private PackageManager mMockPm;
@Mock private Resources mResources;
@Mock private NetworkScorerAppManager.SettingsFacade mSettingsFacade;
+ @Mock private AppOpsManager mAppOpsManager;
private NetworkScorerAppManager mNetworkScorerAppManager;
private List<ResolveInfo> mAvailableServices;
@@ -86,45 +90,69 @@
}
}), eq(PackageManager.GET_META_DATA))).thenReturn(mAvailableServices);
when(mMockContext.getResources()).thenReturn(mResources);
+ when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
+
+ mockLocationModeOn();
+ mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName());
mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext, mSettingsFacade);
}
@Test
public void testGetActiveScorer_providerAvailable() throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertEquals(MOCK_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel());
}
@Test
public void testGetActiveScorer_providerAvailable_serviceLabelOverride() throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
null /* enableUseOpenWifiPackageActivityPackage*/, true /* serviceLabelOverride */);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertEquals(MOCK_OVERRIDEN_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel());
}
@Test
- public void testGetActiveScorer_permissionMissing() throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksDenied(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
+ public void testGetActiveScorer_scoreNetworksPermissionMissing() throws Exception {
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksDenied(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */);
+
+ final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
+ assertNull(activeScorer);
+ }
+
+ @Test
+ public void testGetActiveScorer_locationPermissionMissing() throws Exception {
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockLocationPermissionDenied(PACKAGE_UID, RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */);
+
+ final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
+ assertNull(activeScorer);
+ }
+
+ @Test
+ public void testGetActiveScorer_locationModeOff() throws Exception {
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName());
+ mockLocationModeOff();
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNull(activeScorer);
@@ -133,67 +161,63 @@
@Test
public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotSet()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
null /* enableUseOpenWifiPackageActivityPackage*/);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertNull(activeScorer.getEnableUseOpenWifiActivity());
}
@Test
public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotResolved()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
"package2" /* enableUseOpenWifiPackageActivityPackage*/);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertNull(activeScorer.getEnableUseOpenWifiActivity());
}
@Test
public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityResolved()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertEquals(enableUseOpenWifiComponent, activeScorer.getEnableUseOpenWifiActivity());
assertNull(activeScorer.getNetworkAvailableNotificationChannelId());
}
@Test
public void testGetActiveScorer_providerAvailable_networkAvailableNotificationChannelIdSet() {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
null /* enableUseOpenWifiActivityPackage */, false /* serviceLabelOverride */,
true /* setNotificationChannelId */);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
- assertEquals(924, activeScorer.packageUid);
+ assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent());
+ assertEquals(PACKAGE_UID, activeScorer.packageUid);
assertEquals(MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID,
activeScorer.getNetworkAvailableNotificationChannelId());
}
@@ -209,9 +233,8 @@
@Test
public void testGetActiveScorer_packageSettingIsInvalid() throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
- setDefaultNetworkRecommendationPackage(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
+ setDefaultNetworkRecommendationPackage(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
// NETWORK_RECOMMENDATIONS_PACKAGE is set to a package that isn't a recommender.
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
@@ -249,12 +272,12 @@
@Test
public void testSetActiveScorer_validPackage() throws Exception {
- String packageName = "package";
String newPackage = "newPackage";
- setNetworkRecoPackageSetting(packageName);
+ int newAppUid = 621;
final ComponentName recoComponent = new ComponentName(newPackage, "class1");
mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null);
+ mockRecommendationServiceAvailable(recoComponent, newAppUid, null);
+ mockLocationPermissionGranted(newAppUid, recoComponent.getPackageName());
assertTrue(mNetworkScorerAppManager.setActiveScorer(newPackage));
verify(mSettingsFacade).putString(mMockContext,
@@ -289,11 +312,9 @@
@Test
public void testUpdateState_currentPackageValid() throws Exception {
- String packageName = "package";
- setNetworkRecoPackageSetting(packageName);
- final ComponentName recoComponent = new ComponentName(packageName, "class1");
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null);
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID , null);
mNetworkScorerAppManager.updateState();
@@ -306,11 +327,13 @@
@Test
public void testUpdateState_currentPackageNotValid_validDefault() throws Exception {
- String defaultPackage = "defaultPackage";
- setDefaultNetworkRecommendationPackage(defaultPackage);
+ final String defaultPackage = "defaultPackage";
+ final int defaultAppUid = 621;
final ComponentName recoComponent = new ComponentName(defaultPackage, "class1");
+ setDefaultNetworkRecommendationPackage(defaultPackage);
mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null);
+ mockRecommendationServiceAvailable(recoComponent, defaultAppUid, null);
+ mockLocationPermissionGranted(defaultAppUid, defaultPackage);
mNetworkScorerAppManager.updateState();
@@ -329,8 +352,6 @@
mNetworkScorerAppManager.updateState();
- verify(mSettingsFacade).putString(mMockContext,
- Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, defaultPackage);
verify(mSettingsFacade).putInt(mMockContext,
Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF);
@@ -345,8 +366,9 @@
verify(mSettingsFacade, never()).putString(any(),
eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString());
- verify(mSettingsFacade, never()).putInt(any(),
- eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt());
+ verify(mSettingsFacade).putInt(mMockContext,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF);
}
@Test
@@ -358,8 +380,9 @@
verify(mSettingsFacade, never()).putString(any(),
eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString());
- verify(mSettingsFacade, never()).putInt(any(),
- eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt());
+ verify(mSettingsFacade).putInt(mMockContext,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF);
}
@Test
@@ -370,8 +393,9 @@
mNetworkScorerAppManager.updateState();
- verify(mSettingsFacade, never()).putString(any(),
- eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any());
+ verify(mSettingsFacade).putInt(mMockContext,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF);
}
@Test
@@ -415,11 +439,10 @@
@Test
public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiSettingIsNotEmpty()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
when(mSettingsFacade.getString(mMockContext,
@@ -441,13 +464,12 @@
@Test
public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiActivityNotAvail()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
// The active component doesn't have an open wifi activity so the migration shouldn't
// set USE_OPEN_WIFI_PACKAGE.
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
null /*useOpenWifiActivityPackage*/);
when(mSettingsFacade.getString(mMockContext,
Settings.Global.NETWORK_SCORER_APP))
@@ -466,11 +488,10 @@
@Test
public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_activity()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
// The older network scorer app setting doesn't match the new use open wifi activity package
@@ -492,18 +513,17 @@
@Test
public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_service()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
// The older network scorer app setting doesn't match the active package so the migration
// shouldn't set USE_OPEN_WIFI_PACKAGE.
when(mSettingsFacade.getString(mMockContext,
Settings.Global.NETWORK_SCORER_APP))
- .thenReturn(recoComponent.getPackageName() + ".diff");
+ .thenReturn(RECO_COMPONENT.getPackageName() + ".diff");
when(mSettingsFacade.getString(mMockContext,
Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null);
@@ -518,11 +538,10 @@
@Test
public void testMigrateNetworkScorerAppSettingIfNeeded_packageMatch_activity()
throws Exception {
- final ComponentName recoComponent = new ComponentName("package1", "class1");
final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
- setNetworkRecoPackageSetting(recoComponent.getPackageName());
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+ setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName());
+ mockScoreNetworksGranted(RECO_COMPONENT.getPackageName());
+ mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */,
enableUseOpenWifiComponent.getPackageName());
mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
// Old setting matches the new activity package, migration should happen.
@@ -566,6 +585,33 @@
.thenReturn(PackageManager.PERMISSION_DENIED);
}
+ private void mockLocationModeOn() {
+ mockLocationModeValue(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+ }
+
+ private void mockLocationModeOff() {
+ mockLocationModeValue(Settings.Secure.LOCATION_MODE_OFF);
+ }
+
+ private void mockLocationModeValue(int returnVal) {
+ when(mSettingsFacade.getSecureInt(eq(mMockContext),
+ eq(Settings.Secure.LOCATION_MODE), anyInt())).thenReturn(returnVal);
+ }
+
+ private void mockLocationPermissionGranted(int uid, String packageName) {
+ when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName))
+ .thenReturn(AppOpsManager.MODE_ALLOWED);
+ }
+
+ private void mockLocationPermissionDenied(int uid, String packageName) {
+ when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName))
+ .thenReturn(AppOpsManager.MODE_IGNORED);
+ }
+
private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) {
mockRecommendationServiceAvailable(compName, packageUid, null, false);
}
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
index 45b107d..0e940f2 100644
--- a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
@@ -275,6 +275,11 @@
}
@Override
+ public String[] getNamesForUids(int uid[]) {
+ return null;
+ }
+
+ @Override
public int getUidForSharedUser(String sharedUserName)
throws NameNotFoundException {
return 0;
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 689c8f7..31ed8ba 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -10,6 +10,7 @@
import android.test.AndroidTestCase;
import android.test.RenamingDelegatingContext;
import android.util.Log;
+import android.util.Pair;
import com.android.server.job.JobStore.JobSet;
import com.android.server.job.controllers.JobStatus;
@@ -63,7 +64,7 @@
Thread.sleep(IO_WAIT);
// Manually load tasks from xml file.
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Didn't get expected number of persisted tasks.", 1, jobStatusSet.size());
final JobStatus loadedTaskStatus = jobStatusSet.getAllJobs().get(0);
@@ -98,7 +99,7 @@
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Incorrect # of persisted tasks.", 2, jobStatusSet.size());
Iterator<JobStatus> it = jobStatusSet.getAllJobs().iterator();
JobStatus loaded1 = it.next();
@@ -146,7 +147,7 @@
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
assertTasksEqual(task, loaded.getJob());
@@ -164,7 +165,7 @@
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
assertEquals("Source package not equal.", loaded.getSourcePackageName(),
@@ -185,7 +186,7 @@
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
assertEquals("Period not equal.", loaded.getJob().getIntervalMillis(),
@@ -200,20 +201,23 @@
JobInfo.Builder b = new Builder(8, mComponent)
.setPeriodic(TWO_HOURS, ONE_HOUR)
.setPersisted(true);
+ final long rtcNow = System.currentTimeMillis();
final long invalidLateRuntimeElapsedMillis =
SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS; // > period+flex
final long invalidEarlyRuntimeElapsedMillis =
invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period).
+ final Pair<Long, Long> persistedExecutionTimesUTC = new Pair<>(rtcNow, rtcNow + ONE_HOUR);
final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage",
0 /* sourceUserId */, "someTag",
invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis,
- 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */);
+ 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */,
+ persistedExecutionTimesUTC);
mTaskStoreUnderTest.add(js);
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
@@ -236,7 +240,7 @@
mTaskStoreUnderTest.add(js);
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
assertEquals("Priority not correctly persisted.", 42, loaded.getPriority());
}
@@ -257,7 +261,7 @@
mTaskStoreUnderTest.add(jsPersisted);
Thread.sleep(IO_WAIT);
final JobSet jobStatusSet = new JobSet();
- mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
assertEquals("Job count is incorrect.", 1, jobStatusSet.size());
JobStatus jobStatus = jobStatusSet.getAllJobs().iterator().next();
assertEquals("Wrong job persisted.", 43, jobStatus.getJobId());
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 25ba66e..3cd24b8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -382,6 +382,7 @@
null /*installUser*/,
false /*allowInstall*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -423,6 +424,7 @@
UserHandle.SYSTEM /*installUser*/,
true /*allowInstall*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -467,6 +469,7 @@
null /*installUser*/,
false /*allowInstall*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -511,6 +514,7 @@
null /*installUser*/,
false /*allowInstall*/,
false /*instantApp*/,
+ false /*virtualPreload*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index afc0f67..4db9a30 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -23,10 +23,14 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.PathClassLoader;
import dalvik.system.VMRuntime;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -48,6 +52,10 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class DexManagerTests {
+ private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
+ private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
+ DelegateLastClassLoader.class.getName();
+
private DexManager mDexManager;
private TestData mFooUser0;
@@ -56,6 +64,9 @@
private TestData mInvalidIsa;
private TestData mDoesNotExist;
+ private TestData mBarUser0UnsupportedClassLoader;
+ private TestData mBarUser0DelegateLastClassLoader;
+
private int mUser0;
private int mUser1;
@@ -68,12 +79,17 @@
String foo = "foo";
String bar = "bar";
- mFooUser0 = new TestData(foo, isa, mUser0);
- mBarUser0 = new TestData(bar, isa, mUser0);
- mBarUser1 = new TestData(bar, isa, mUser1);
+ mFooUser0 = new TestData(foo, isa, mUser0, PATH_CLASS_LOADER_NAME);
+ mBarUser0 = new TestData(bar, isa, mUser0, PATH_CLASS_LOADER_NAME);
+ mBarUser1 = new TestData(bar, isa, mUser1, PATH_CLASS_LOADER_NAME);
mInvalidIsa = new TestData("INVALID", "INVALID_ISA", mUser0);
mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1);
+ mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0,
+ "unsupported.class_loader");
+ mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0,
+ DELEGATE_LAST_CLASS_LOADER_NAME);
+
mDexManager = new DexManager(null, null, null, null);
// Foo and Bar are available to user0.
@@ -90,7 +106,7 @@
notifyDexLoad(mFooUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser0);
// Package is not used by others, so we should get nothing back.
- assertNull(getPackageUseInfo(mFooUser0));
+ assertNoUseInfo(mFooUser0);
}
@Test
@@ -100,8 +116,7 @@
// Bar is used by others now and should be in our records
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNotNull(pui);
- assertTrue(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mBarUser0, pui, true);
assertTrue(pui.getDexUseInfoMap().isEmpty());
}
@@ -112,8 +127,7 @@
notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(mFooUser0);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mFooUser0, pui, false);
assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
}
@@ -125,8 +139,7 @@
notifyDexLoad(mFooUser0, barSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mBarUser0, pui, false);
assertEquals(barSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(mFooUser0, pui, barSecondaries, /*isUsedByOtherApps*/true, mUser0);
}
@@ -149,8 +162,7 @@
// Check bar usage. Should be used by other app (for primary and barSecondaries).
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNotNull(pui);
- assertTrue(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mBarUser0, pui, true);
assertEquals(barSecondaries.size() + barSecondariesForOwnUse.size(),
pui.getDexUseInfoMap().size());
@@ -160,8 +172,7 @@
// Check foo usage. Should not be used by other app.
pui = getPackageUseInfo(mFooUser0);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mFooUser0, pui, false);
assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
}
@@ -169,22 +180,22 @@
@Test
public void testPackageUseInfoNotFound() {
// Assert we don't get back data we did not previously record.
- assertNull(getPackageUseInfo(mFooUser0));
+ assertNoUseInfo(mFooUser0);
}
@Test
public void testInvalidIsa() {
// Notifying with an invalid ISA should be ignored.
notifyDexLoad(mInvalidIsa, mInvalidIsa.getSecondaryDexPaths(), mUser0);
- assertNull(getPackageUseInfo(mInvalidIsa));
+ assertNoUseInfo(mInvalidIsa);
}
@Test
- public void testNotExistingPackate() {
+ public void testNotExistingPackage() {
// Notifying about the load of a package which was previously not
// register in DexManager#load should be ignored.
notifyDexLoad(mDoesNotExist, mDoesNotExist.getBaseAndSplitDexPaths(), mUser0);
- assertNull(getPackageUseInfo(mDoesNotExist));
+ assertNoUseInfo(mDoesNotExist);
}
@Test
@@ -192,7 +203,7 @@
// Bar from User1 tries to load secondary dex files from User0 Bar.
// Request should be ignored.
notifyDexLoad(mBarUser1, mBarUser0.getSecondaryDexPaths(), mUser1);
- assertNull(getPackageUseInfo(mBarUser1));
+ assertNoUseInfo(mBarUser1);
}
@Test
@@ -201,7 +212,7 @@
// Note that the PackageManagerService already filters this out but we
// still check that nothing goes unexpected in DexManager.
notifyDexLoad(mBarUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser1);
- assertNull(getPackageUseInfo(mBarUser1));
+ assertNoUseInfo(mBarUser1);
}
@Test
@@ -213,7 +224,7 @@
// Before we notify about the installation of the newPackage if mFoo
// is trying to load something from it we should not find it.
notifyDexLoad(mFooUser0, newSecondaries, mUser0);
- assertNull(getPackageUseInfo(newPackage));
+ assertNoUseInfo(newPackage);
// Notify about newPackage install and let mFoo load its dexes.
mDexManager.notifyPackageInstalled(newPackage.mPackageInfo, mUser0);
@@ -221,8 +232,7 @@
// We should get back the right info.
PackageUseInfo pui = getPackageUseInfo(newPackage);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(newPackage, pui, false);
assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/true, mUser0);
}
@@ -238,8 +248,7 @@
notifyDexLoad(newPackage, newSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(newPackage);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(newPackage, pui, false);
assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/false, mUser0);
}
@@ -251,8 +260,7 @@
// Bar is used by others now and should be in our records.
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNotNull(pui);
- assertTrue(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mBarUser0, pui, true);
assertTrue(pui.getDexUseInfoMap().isEmpty());
// Notify that bar is updated.
@@ -262,8 +270,7 @@
// The usedByOtherApps flag should be clear now.
pui = getPackageUseInfo(mBarUser0);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mBarUser0, pui, false);
}
@Test
@@ -275,8 +282,7 @@
// We shouldn't find yet the new split as we didn't notify the package update.
notifyDexLoad(mFooUser0, newSplits, mUser0);
- PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNull(pui);
+ assertNoUseInfo(mBarUser0);
// Notify that bar is updated. splitSourceDirs will contain the updated path.
mDexManager.notifyPackageUpdated(mBarUser0.getPackageName(),
@@ -285,9 +291,9 @@
// Now, when the split is loaded we will find it and we should mark Bar as usedByOthers.
notifyDexLoad(mFooUser0, newSplits, mUser0);
- pui = getPackageUseInfo(mBarUser0);
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0);
assertNotNull(pui);
- assertTrue(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(newSplits, pui, true);
}
@Test
@@ -319,8 +325,7 @@
// Foo should still be around since it's used by other apps but with no
// secondary dex info.
PackageUseInfo pui = getPackageUseInfo(mFooUser0);
- assertNotNull(pui);
- assertTrue(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mFooUser0, pui, true);
assertTrue(pui.getDexUseInfoMap().isEmpty());
}
@@ -334,8 +339,7 @@
// Foo should not be around since all its secondary dex info were deleted
// and it is not used by other apps.
- PackageUseInfo pui = getPackageUseInfo(mFooUser0);
- assertNull(pui);
+ assertNoUseInfo(mFooUser0);
}
@Test
@@ -347,8 +351,7 @@
mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), UserHandle.USER_ALL);
// Bar should not be around since it was removed for all users.
- PackageUseInfo pui = getPackageUseInfo(mBarUser0);
- assertNull(pui);
+ assertNoUseInfo(mBarUser0);
}
@Test
@@ -357,7 +360,7 @@
// Load a dex file from framework.
notifyDexLoad(mFooUser0, Arrays.asList(frameworkDex), mUser0);
// The dex file should not be recognized as a package.
- assertNull(mDexManager.getPackageUseInfo(frameworkDex));
+ assertFalse(mDexManager.hasInfoOnPackage(frameworkDex));
}
@Test
@@ -367,14 +370,83 @@
notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
PackageUseInfo pui = getPackageUseInfo(mFooUser0);
- assertNotNull(pui);
- assertFalse(pui.isUsedByOtherApps());
+ assertIsUsedByOtherApps(mFooUser0, pui, false);
assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
}
+ @Test
+ public void testNotifyUnsupportedClassLoader() {
+ List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
+ notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
+
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+ assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
+ assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+ // We expect that all the contexts are unsupported.
+ String[] expectedContexts =
+ Collections.nCopies(secondaries.size(),
+ PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+ assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+ /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+ }
+
+ @Test
+ public void testNotifyVariableClassLoader() {
+ // Record bar secondaries with the default PathClassLoader.
+ List<String> secondaries = mBarUser0.getSecondaryDexPaths();
+
+ notifyDexLoad(mBarUser0, secondaries, mUser0);
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+ assertIsUsedByOtherApps(mBarUser0, pui, false);
+ assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+ assertSecondaryUse(mFooUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
+
+ // Record bar secondaries again with a different class loader. This will change the context.
+ notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
+
+ pui = getPackageUseInfo(mBarUser0);
+ assertIsUsedByOtherApps(mBarUser0, pui, false);
+ assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+ // We expect that all the contexts to be changed to variable now.
+ String[] expectedContexts =
+ Collections.nCopies(secondaries.size(),
+ PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+ assertSecondaryUse(mFooUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0,
+ expectedContexts);
+ }
+
+ @Test
+ public void testNotifyUnsupportedClassLoaderDoesNotChange() {
+ List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
+ notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
+
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+ assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
+ assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
+ // We expect that all the contexts are unsupported.
+ String[] expectedContexts =
+ Collections.nCopies(secondaries.size(),
+ PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
+ assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+ /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+
+ // Record bar secondaries again with a different class loader. This will change the context.
+ // However, because the context was already marked as unsupported we should not chage it.
+ notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
+ pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
+ assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
+ /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+
+ }
+
+
private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
- List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
+ List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId,
+ String[] expectedContexts) {
+ assertNotNull(expectedContexts);
+ assertEquals(expectedContexts.length, secondaries.size());
+ int index = 0;
for (String dex : secondaries) {
DexUseInfo dui = pui.getDexUseInfoMap().get(dex);
assertNotNull(dui);
@@ -382,16 +454,50 @@
assertEquals(ownerUserId, dui.getOwnerUserId());
assertEquals(1, dui.getLoaderIsas().size());
assertTrue(dui.getLoaderIsas().contains(testData.mLoaderIsa));
+ assertEquals(expectedContexts[index++], dui.getClassLoaderContext());
}
}
+ private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
+ List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
+ String[] expectedContexts = DexoptUtils.processContextForDexLoad(
+ Arrays.asList(testData.mClassLoader),
+ Arrays.asList(String.join(File.pathSeparator, secondaries)));
+ assertSecondaryUse(testData, pui, secondaries, isUsedByOtherApps, ownerUserId,
+ expectedContexts);
+ }
+ private void assertIsUsedByOtherApps(TestData testData, PackageUseInfo pui,
+ boolean isUsedByOtherApps) {
+ assertIsUsedByOtherApps(testData.getBaseAndSplitDexPaths(), pui, isUsedByOtherApps);
+ }
+
+ private void assertIsUsedByOtherApps(List<String> codePaths, PackageUseInfo pui,
+ boolean isUsedByOtherApps) {
+ for (String codePath : codePaths) {
+ assertEquals(codePath, isUsedByOtherApps, pui.isUsedByOtherApps(codePath));
+ }
+ }
private void notifyDexLoad(TestData testData, List<String> dexPaths, int loaderUserId) {
- mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, dexPaths,
+ // By default, assume a single class loader in the chain.
+ // This makes writing tests much easier.
+ List<String> classLoaders = Arrays.asList(testData.mClassLoader);
+ List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths));
+ notifyDexLoad(testData, classLoaders, classPaths, loaderUserId);
+ }
+
+ private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths,
+ int loaderUserId) {
+ mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths,
testData.mLoaderIsa, loaderUserId);
}
private PackageUseInfo getPackageUseInfo(TestData testData) {
- return mDexManager.getPackageUseInfo(testData.mPackageInfo.packageName);
+ assertTrue(mDexManager.hasInfoOnPackage(testData.mPackageInfo.packageName));
+ return mDexManager.getPackageUseInfoOrDefault(testData.mPackageInfo.packageName);
+ }
+
+ private void assertNoUseInfo(TestData testData) {
+ assertFalse(mDexManager.hasInfoOnPackage(testData.mPackageInfo.packageName));
}
private static PackageInfo getMockPackageInfo(String packageName, int userId) {
@@ -416,10 +522,16 @@
private static class TestData {
private final PackageInfo mPackageInfo;
private final String mLoaderIsa;
+ private final String mClassLoader;
- private TestData(String packageName, String loaderIsa, int userId) {
+ private TestData(String packageName, String loaderIsa, int userId, String classLoader) {
mPackageInfo = getMockPackageInfo(packageName, userId);
mLoaderIsa = loaderIsa;
+ mClassLoader = classLoader;
+ }
+
+ private TestData(String packageName, String loaderIsa, int userId) {
+ this(packageName, loaderIsa, userId, PATH_CLASS_LOADER_NAME);
}
private String getPackageName() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
index 1eb5552..b64716c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
@@ -62,7 +62,8 @@
DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
DexoptOptions.DEXOPT_ONLY_SHARED_DEX |
- DexoptOptions.DEXOPT_DOWNGRADE;
+ DexoptOptions.DEXOPT_DOWNGRADE |
+ DexoptOptions.DEXOPT_AS_SHARED_LIBRARY;
DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, flags);
assertEquals(mPackageName, opt.getPackageName());
@@ -74,6 +75,7 @@
assertTrue(opt.isDexoptOnlySharedDex());
assertTrue(opt.isDowngrade());
assertTrue(opt.isForce());
+ assertTrue(opt.isDexoptAsSharedLibrary());
}
@Test
@@ -89,7 +91,7 @@
PackageManagerService.REASON_INSTALL,
PackageManagerService.REASON_BACKGROUND_DEXOPT,
PackageManagerService.REASON_AB_OTA,
- PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE};
+ PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE,};
for (int reason : reasons) {
DexoptOptions opt = new DexoptOptions(mPackageName, reason, flags);
@@ -102,6 +104,7 @@
assertFalse(opt.isDexoptOnlySharedDex());
assertFalse(opt.isDowngrade());
assertTrue(opt.isForce());
+ assertFalse(opt.isDexoptAsSharedLibrary());
}
}
@@ -119,6 +122,7 @@
assertFalse(opt.isDexoptOnlySharedDex());
assertFalse(opt.isDowngrade());
assertTrue(opt.isForce());
+ assertFalse(opt.isDexoptAsSharedLibrary());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 47918ea..2c56a82 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -17,6 +17,9 @@
package com.android.server.pm.dex;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import android.content.pm.ApplicationInfo;
import android.support.test.filters.SmallTest;
@@ -24,14 +27,21 @@
import android.util.SparseArray;
import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
@RunWith(AndroidJUnit4.class)
@SmallTest
public class DexoptUtilsTest {
+ private static final String DEX_CLASS_LOADER_NAME = DexClassLoader.class.getName();
private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
DelegateLastClassLoader.class.getName();
@@ -57,7 +67,7 @@
DELEGATE_LAST_CLASS_LOADER_NAME,
DELEGATE_LAST_CLASS_LOADER_NAME,
PATH_CLASS_LOADER_NAME,
- PATH_CLASS_LOADER_NAME,
+ DEX_CLASS_LOADER_NAME,
PATH_CLASS_LOADER_NAME,
null}; // A null class loader name should default to PathClassLoader.
if (addSplitDependencies) {
@@ -210,4 +220,68 @@
assertEquals(1, contexts.length);
assertEquals("DLC[]", contexts[0]);
}
+
+ @Test
+ public void testProcessContextForDexLoad() {
+ List<String> classLoaders = Arrays.asList(
+ DELEGATE_LAST_CLASS_LOADER_NAME,
+ PATH_CLASS_LOADER_NAME,
+ PATH_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(
+ String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+ String.join(File.pathSeparator, "parent1.dex"),
+ String.join(File.pathSeparator, "parent2.dex", "parent3.dex"));
+ String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+ assertNotNull(context);
+ assertEquals(2, context.length);
+ assertEquals("DLC[];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[0]);
+ assertEquals("DLC[foo.dex];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[1]);
+ }
+
+ @Test
+ public void testProcessContextForDexLoadSingleElement() {
+ List<String> classLoaders = Arrays.asList(PATH_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(
+ String.join(File.pathSeparator, "foo.dex", "bar.dex", "zoo.dex"));
+ String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+ assertNotNull(context);
+ assertEquals(3, context.length);
+ assertEquals("PCL[]", context[0]);
+ assertEquals("PCL[foo.dex]", context[1]);
+ assertEquals("PCL[foo.dex:bar.dex]", context[2]);
+ }
+
+ @Test
+ public void testProcessContextForDexLoadUnsupported() {
+ List<String> classLoaders = Arrays.asList(
+ DELEGATE_LAST_CLASS_LOADER_NAME,
+ "unsupported.class.loader");
+ List<String> classPaths = Arrays.asList(
+ String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+ String.join(File.pathSeparator, "parent1.dex"));
+ String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+ assertNull(context);
+ }
+
+ @Test
+ public void testProcessContextForDexLoadIllegalCallEmptyList() {
+ boolean gotException = false;
+ try {
+ DexoptUtils.processContextForDexLoad(Collections.emptyList(), Collections.emptyList());
+ } catch (IllegalArgumentException ignore) {
+ gotException = true;
+ }
+ assertTrue(gotException);
+ }
+
+ @Test
+ public void testProcessContextForDexLoadIllegalCallDifferentSize() {
+ boolean gotException = false;
+ try {
+ DexoptUtils.processContextForDexLoad(Collections.emptyList(), Arrays.asList("a"));
+ } catch (IllegalArgumentException ignore) {
+ gotException = true;
+ }
+ assertTrue(gotException);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index e1ef41e..69a148d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -21,6 +21,7 @@
import android.support.test.runner.AndroidJUnit4;
import dalvik.system.VMRuntime;
+import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -249,7 +250,10 @@
Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
packageToUsersMap.put(mBarSecondary2User1.mPackageName,
new HashSet<>(Arrays.asList(mBarSecondary2User1.mOwnerUserId)));
- mPackageDexUsage.syncData(packageToUsersMap);
+ Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+ packageToCodePaths.put(mBarBaseUser0.mPackageName,
+ new HashSet<>(Arrays.asList(mBarBaseUser0.mDexFile)));
+ mPackageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
// Assert that only user 1 files are there.
assertPackageDexUsage(mBarBaseUser0, mBarSecondary2User1);
@@ -341,8 +345,8 @@
Set<String> usersExtra = new HashSet<>(Arrays.asList(
new String[] {"another.package.2", "another.package.3"}));
- assertTrue(record(packageDexUsageRecordUsers, mFooBaseUser0, users));
- assertTrue(record(packageDexUsageRecordUsers, mFooBaseUser0, usersExtra));
+ assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, users));
+ assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, usersExtra));
assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, users));
assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, usersExtra));
@@ -351,7 +355,7 @@
// Verify that the users were recorded.
Set<String> userAll = new HashSet<>(users);
userAll.addAll(usersExtra);
- assertPackageDexUsage(packageDexUsageRecordUsers, userAll, mFooBaseUser0,
+ assertPackageDexUsage(packageDexUsageRecordUsers, userAll, mFooSplit2UsedByOtherApps0,
mFooSecondary1User0);
}
@@ -359,22 +363,178 @@
public void testRecordDexFileUsersNotTheOwningPackage() {
PackageDexUsage packageDexUsageRecordUsers = new PackageDexUsage();
Set<String> users = new HashSet<>(Arrays.asList(
- new String[] {mFooBaseUser0.mPackageName,}));
+ new String[] {mFooSplit2UsedByOtherApps0.mPackageName}));
Set<String> usersExtra = new HashSet<>(Arrays.asList(
new String[] {"another.package.2", "another.package.3"}));
- assertTrue(record(packageDexUsageRecordUsers, mFooBaseUser0, users));
- assertTrue(record(packageDexUsageRecordUsers, mFooBaseUser0, usersExtra));
+ assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, users));
+ assertTrue(record(packageDexUsageRecordUsers, mFooSplit2UsedByOtherApps0, usersExtra));
assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, users));
assertTrue(record(packageDexUsageRecordUsers, mFooSecondary1User0, usersExtra));
packageDexUsageRecordUsers = writeAndReadBack(packageDexUsageRecordUsers);
// Verify that only the non owning packages were recorded.
- assertPackageDexUsage(packageDexUsageRecordUsers, usersExtra, mFooBaseUser0,
+ assertPackageDexUsage(packageDexUsageRecordUsers, usersExtra, mFooSplit2UsedByOtherApps0,
mFooSecondary1User0);
}
+ @Test
+ public void testRecordClassLoaderContextVariableContext() {
+ // Record a secondary dex file.
+ assertTrue(record(mFooSecondary1User0));
+ // Now update its context.
+ TestData fooSecondary1User0NewContext = mFooSecondary1User0.updateClassLoaderContext(
+ "PCL[new_context.dex]");
+ assertTrue(record(fooSecondary1User0NewContext));
+
+ // Not check that the context was switch to variable.
+ TestData expectedContext = mFooSecondary1User0.updateClassLoaderContext(
+ PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT);
+
+ assertPackageDexUsage(null, expectedContext);
+ writeAndReadBack();
+ assertPackageDexUsage(null, expectedContext);
+ }
+
+ @Test
+ public void testRecordClassLoaderContextUnsupportedContext() {
+ // Record a secondary dex file.
+ assertTrue(record(mFooSecondary1User0));
+ // Now update its context.
+ TestData unsupportedContext = mFooSecondary1User0.updateClassLoaderContext(
+ PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT);
+ assertTrue(record(unsupportedContext));
+
+ assertPackageDexUsage(null, unsupportedContext);
+ writeAndReadBack();
+ assertPackageDexUsage(null, unsupportedContext);
+ }
+
+ @Test
+ public void testRecordClassLoaderContextTransitionFromUnknown() {
+ // Record a secondary dex file.
+ TestData unknownContext = mFooSecondary1User0.updateClassLoaderContext(
+ PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT);
+ assertTrue(record(unknownContext));
+
+ assertPackageDexUsage(null, unknownContext);
+ writeAndReadBack();
+ assertPackageDexUsage(null, unknownContext);
+
+ // Now update the secondary dex record with a class loader context. This simulates the
+ // version 2 to version 3 upgrade.
+
+ assertTrue(record(mFooSecondary1User0));
+
+ assertPackageDexUsage(null, mFooSecondary1User0);
+ writeAndReadBack();
+ assertPackageDexUsage(null, mFooSecondary1User0);
+ }
+
+ @Test
+ public void testDexUsageClassLoaderContext() {
+ final boolean isUsedByOtherApps = false;
+ final int userId = 0;
+ PackageDexUsage.DexUseInfo validContext = new DexUseInfo(isUsedByOtherApps, userId,
+ "valid_context", "arm");
+ assertFalse(validContext.isUnknownClassLoaderContext());
+ assertFalse(validContext.isUnsupportedClassLoaderContext());
+ assertFalse(validContext.isVariableClassLoaderContext());
+
+ PackageDexUsage.DexUseInfo unsupportedContext = new DexUseInfo(isUsedByOtherApps, userId,
+ PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT, "arm");
+ assertFalse(unsupportedContext.isUnknownClassLoaderContext());
+ assertTrue(unsupportedContext.isUnsupportedClassLoaderContext());
+ assertFalse(unsupportedContext.isVariableClassLoaderContext());
+
+ PackageDexUsage.DexUseInfo variableContext = new DexUseInfo(isUsedByOtherApps, userId,
+ PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT, "arm");
+ assertFalse(variableContext.isUnknownClassLoaderContext());
+ assertFalse(variableContext.isUnsupportedClassLoaderContext());
+ assertTrue(variableContext.isVariableClassLoaderContext());
+
+ PackageDexUsage.DexUseInfo unknownContext = new DexUseInfo(isUsedByOtherApps, userId,
+ PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT, "arm");
+ assertTrue(unknownContext.isUnknownClassLoaderContext());
+ assertFalse(unknownContext.isUnsupportedClassLoaderContext());
+ assertFalse(unknownContext.isVariableClassLoaderContext());
+ }
+
+ @Test
+ public void testReadVersion1() {
+ String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
+ // Equivalent to
+ // record(mFooSplit2UsedByOtherApps0);
+ // record(mFooSecondary1User0);
+ // record(mFooSecondary2UsedByOtherApps0);
+ // record(mBarBaseUser0);
+ // record(mBarSecondary1User0);
+ String content = "PACKAGE_MANAGER__PACKAGE_DEX_USAGE__1\n"
+ + "com.google.foo,1\n"
+ + "#/data/user/0/com.google.foo/sec-1.dex\n"
+ + "0,0," + isa + "\n"
+ + "#/data/user/0/com.google.foo/sec-2.dex\n"
+ + "0,1," + isa + "\n"
+ + "com.google.bar,0\n"
+ + "#/data/user/0/com.google.bar/sec-1.dex\n"
+ + "0,0," + isa + "\n";
+
+ PackageDexUsage packageDexUsage = new PackageDexUsage();
+ try {
+ packageDexUsage.read(new StringReader(content));
+ } catch (IOException e) {
+ fail();
+ }
+
+ // After the read we must sync the data to fill the missing information on the code paths.
+ Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
+ Map<String, Set<String>> packageToCodePaths = new HashMap<>();
+
+ // Handle foo package.
+ packageToUsersMap.put(mFooSplit2UsedByOtherApps0.mPackageName,
+ new HashSet<>(Arrays.asList(mFooSplit2UsedByOtherApps0.mOwnerUserId)));
+ packageToCodePaths.put(mFooSplit2UsedByOtherApps0.mPackageName,
+ new HashSet<>(Arrays.asList(mFooSplit2UsedByOtherApps0.mDexFile,
+ mFooSplit1User0.mDexFile, mFooBaseUser0.mDexFile)));
+ // Handle bar package.
+ packageToUsersMap.put(mBarBaseUser0.mPackageName,
+ new HashSet<>(Arrays.asList(mBarBaseUser0.mOwnerUserId)));
+ packageToCodePaths.put(mBarBaseUser0.mPackageName,
+ new HashSet<>(Arrays.asList(mBarBaseUser0.mDexFile)));
+
+ // Sync the data.
+ packageDexUsage.syncData(packageToUsersMap, packageToCodePaths);
+
+ // Update the class loaders to unknown before asserting if needed. Before version 2 we
+ // didn't have any.
+ String unknown = PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT;
+ TestData fooBaseUser0 = mFooBaseUser0.updateClassLoaderContext(unknown);
+ TestData fooSplit1User0 = mFooSplit1User0.updateClassLoaderContext(unknown);
+ TestData fooSplit2UsedByOtherApps0 =
+ mFooSplit2UsedByOtherApps0.updateClassLoaderContext(unknown);
+ TestData fooSecondary1User0 = mFooSecondary1User0.updateClassLoaderContext(unknown);
+ TestData fooSecondary2UsedByOtherApps0 =
+ mFooSecondary2UsedByOtherApps0.updateClassLoaderContext(unknown);
+ TestData barBaseUser0 = mBarBaseUser0.updateClassLoaderContext(unknown);
+ TestData barSecondary1User0 = mBarSecondary1User0.updateClassLoaderContext(unknown);
+
+ // Assert foo code paths. Note that we ignore the users during upgrade.
+ final Set<String> ignoredUsers = null;
+ assertPackageDexUsage(packageDexUsage, ignoredUsers,
+ fooSplit2UsedByOtherApps0, fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+ // Because fooSplit2UsedByOtherApps0 is used by others, all the other code paths must
+ // share the same data.
+ assertPackageDexUsage(packageDexUsage, ignoredUsers,
+ fooSplit1User0.updateUseByOthers(true),
+ fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+ assertPackageDexUsage(packageDexUsage, ignoredUsers, fooBaseUser0.updateUseByOthers(true),
+ fooSecondary1User0, fooSecondary2UsedByOtherApps0);
+
+ // Assert bar code paths. Note that we ignore the users during upgrade.
+ assertPackageDexUsage(packageDexUsage, ignoredUsers, barBaseUser0, barSecondary1User0);
+ }
+
private void assertPackageDexUsage(TestData primary, TestData... secondaries) {
assertPackageDexUsage(mPackageDexUsage, null, primary, secondaries);
}
@@ -382,14 +542,16 @@
private void assertPackageDexUsage(PackageDexUsage packageDexUsage, Set<String> users,
TestData primary, TestData... secondaries) {
String packageName = primary == null ? secondaries[0].mPackageName : primary.mPackageName;
- boolean primaryUsedByOtherApps = primary == null ? false : primary.mUsedByOtherApps;
+ boolean primaryUsedByOtherApps = primary != null && primary.mUsedByOtherApps;
PackageUseInfo pInfo = packageDexUsage.getPackageUseInfo(packageName);
// Check package use info
assertNotNull(pInfo);
- assertEquals(primaryUsedByOtherApps, pInfo.isUsedByOtherApps());
- if (users != null) {
- assertEquals(pInfo.getLoadingPackages(), users);
+ if (primary != null) {
+ assertEquals(primaryUsedByOtherApps, pInfo.isUsedByOtherApps(primary.mDexFile));
+ if (users != null) {
+ assertEquals(pInfo.getLoadingPackages(primary.mDexFile), users);
+ }
}
Map<String, DexUseInfo> dexUseInfoMap = pInfo.getDexUseInfoMap();
@@ -406,13 +568,15 @@
if (users != null) {
assertEquals(dInfo.getLoadingPackages(), users);
}
+
+ assertEquals(testData.mClassLoaderContext, dInfo.getClassLoaderContext());
}
}
private boolean record(TestData testData) {
return mPackageDexUsage.record(testData.mPackageName, testData.mDexFile,
testData.mOwnerUserId, testData.mLoaderIsa, testData.mUsedByOtherApps,
- testData.mPrimaryOrSplit, testData.mUsedBy);
+ testData.mPrimaryOrSplit, testData.mUsedBy, testData.mClassLoaderContext);
}
private boolean record(PackageDexUsage packageDexUsage, TestData testData, Set<String> users) {
@@ -420,7 +584,7 @@
for (String user : users) {
result = result && packageDexUsage.record(testData.mPackageName, testData.mDexFile,
testData.mOwnerUserId, testData.mLoaderIsa, testData.mUsedByOtherApps,
- testData.mPrimaryOrSplit, user);
+ testData.mPrimaryOrSplit, user, testData.mClassLoaderContext);
}
return result;
}
@@ -451,9 +615,16 @@
private final boolean mUsedByOtherApps;
private final boolean mPrimaryOrSplit;
private final String mUsedBy;
+ private final String mClassLoaderContext;
private TestData(String packageName, String dexFile, int ownerUserId,
- String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String usedBy) {
+ String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String usedBy) {
+ this(packageName, dexFile, ownerUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
+ usedBy, "DefaultClassLoaderContextFor_" + dexFile);
+ }
+ private TestData(String packageName, String dexFile, int ownerUserId,
+ String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String usedBy,
+ String classLoaderContext) {
mPackageName = packageName;
mDexFile = dexFile;
mOwnerUserId = ownerUserId;
@@ -461,7 +632,17 @@
mUsedByOtherApps = isUsedByOtherApps;
mPrimaryOrSplit = primaryOrSplit;
mUsedBy = usedBy;
+ mClassLoaderContext = classLoaderContext;
}
+ private TestData updateClassLoaderContext(String newContext) {
+ return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa, mUsedByOtherApps,
+ mPrimaryOrSplit, mUsedBy, newContext);
+ }
+
+ private TestData updateUseByOthers(boolean newUsedByOthers) {
+ return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa, newUsedByOthers,
+ mPrimaryOrSplit, mUsedBy, mClassLoaderContext);
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
index f7ea0c4..432cfc7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -57,9 +57,10 @@
final Configuration config = new Configuration();
final Configuration config2 = new Configuration();
config.appBounds = new Rect(0, 1, 1, 0);
- config2.appBounds = new Rect(0, 2, 2, 0);
+ config2.appBounds = new Rect(1, 2, 2, 1);
- assertEquals(ActivityInfo.CONFIG_APP_BOUNDS, config.diff(config2));
+ assertEquals(ActivityInfo.CONFIG_SCREEN_SIZE, config.diff(config2));
+ assertEquals(0, config.diffPublicOnly(config2));
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 36083bf..b09601e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -185,6 +185,11 @@
assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
// Can specify orientation if the current orientation candidate is orientation behind.
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND));
+
+ token.sendingToBottom = false;
+ token.setIsOnTop(true);
+ // Allow for token to provide orientation hidden if on top and not being sent to bottom.
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 856e940..91eb55b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -31,10 +31,13 @@
import org.junit.runner.RunWith;
import android.content.res.Configuration;
+import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
import android.util.SparseIntArray;
+import android.view.MotionEvent;
import java.util.Arrays;
import java.util.LinkedList;
@@ -237,6 +240,52 @@
assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
}
+ /**
+ * Tests tapping on a stack in different display results in window gaining focus.
+ */
+ @Test
+ public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
+ DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
+ // Create a second display
+ final DisplayContent dc1 = createNewDisplay();
+
+ // Add stack with activity.
+ final TaskStack stack0 = createTaskStackOnDisplay(dc0);
+ final Task task0 = createTaskInStack(stack0, 0 /* userId */);
+ final WindowTestUtils.TestAppWindowToken token =
+ new WindowTestUtils.TestAppWindowToken(dc0);
+ task0.addChild(token, 0);
+ dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+ sWm.registerPointerEventListener(dc0.mTapDetector);
+ final TaskStack stack1 = createTaskStackOnDisplay(dc1);
+ final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+ final WindowTestUtils.TestAppWindowToken token1 =
+ new WindowTestUtils.TestAppWindowToken(dc0);
+ task1.addChild(token1, 0);
+ dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+ sWm.registerPointerEventListener(dc1.mTapDetector);
+
+ // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
+ DisplayMetrics dm0 = dc0.getDisplayMetrics();
+ dc0.mTapDetector.onPointerEvent(
+ createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
+ dc0.mTapDetector.onPointerEvent(
+ createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
+
+ // Check focus is on primary display.
+ assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
+
+ // Tap on secondary display
+ DisplayMetrics dm1 = dc1.getDisplayMetrics();
+ dc1.mTapDetector.onPointerEvent(
+ createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
+ dc1.mTapDetector.onPointerEvent(
+ createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
+
+ // Check focus is on secondary.
+ assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+ }
+
@Test
@Ignore
public void testFocusedWindowMultipleDisplays() throws Exception {
@@ -355,4 +404,18 @@
}
assertTrue(actualWindows.isEmpty());
}
+
+ private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis() + 100;
+ final int metaState = 0;
+
+ return MotionEvent.obtain(
+ downTime,
+ eventTime,
+ isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
+ x,
+ y,
+ metaState);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 828d405..95adc9c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -18,6 +18,10 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -39,6 +43,7 @@
import android.os.RemoteException;
import android.view.Display;
import android.view.IWindowManager;
+import android.view.InputChannel;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
@@ -91,7 +96,14 @@
}).when(am).notifyKeyguardFlagsChanged(any());
}
- sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false,
+ InputManagerService ims = mock(InputManagerService.class);
+ // InputChannel is final and can't be mocked.
+ InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
+ if (input != null && input.length > 1) {
+ doReturn(input[1]).when(ims).monitorInput(anyString());
+ }
+
+ sWm = WindowManagerService.main(context, ims, true, false,
false, new TestWindowManagerPolicy());
}
return sWm;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index b83532c..7ff1110 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -89,6 +89,7 @@
/** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
public static class TestAppWindowToken extends AppWindowToken {
+ boolean mOnTop = false;
TestAppWindowToken(DisplayContent dc) {
super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */,
@@ -125,6 +126,15 @@
int positionInParent() {
return getParent().mChildren.indexOf(this);
}
+
+ void setIsOnTop(boolean onTop) {
+ mOnTop = onTop;
+ }
+
+ @Override
+ boolean isOnTop() {
+ return mOnTop;
+ }
}
/* Used so we can gain access to some protected members of the {@link WindowToken} class */
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 184dd73..774bf43 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1153,8 +1153,7 @@
.usb_unsupported_audio_accessory_message);
}
- Notification notification =
- new Notification.Builder(mContext, channel)
+ Notification.Builder builder = new Notification.Builder(mContext, channel)
.setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
.setWhen(0)
.setOngoing(true)
@@ -1166,8 +1165,15 @@
.setContentTitle(title)
.setContentText(message)
.setContentIntent(pi)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .build();
+ .setVisibility(Notification.VISIBILITY_PUBLIC);
+
+ if (titleRes
+ == com.android.internal.R.string
+ .usb_unsupported_audio_accessory_title) {
+ builder.setStyle(new Notification.BigTextStyle()
+ .bigText(message));
+ }
+ Notification notification = builder.build();
mNotificationManager.notifyAsUser(null, id, notification,
UserHandle.ALL);
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 303a577..d4a0ac4 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -123,21 +123,27 @@
ByteStream stream = new ByteStream(descriptors);
while (stream.available() > 0) {
- UsbDescriptor descriptor = allocDescriptor(stream);
+ UsbDescriptor descriptor = null;
+ try {
+ descriptor = allocDescriptor(stream);
+ } catch (Exception ex) {
+ Log.e(TAG, "Exception allocating USB descriptor.", ex);
+ }
+
if (descriptor != null) {
// Parse
try {
descriptor.parseRawDescriptors(stream);
+
+ // Its OK to add the invalid descriptor as the postParse()
+ // routine will mark it as invalid.
+ mDescriptors.add(descriptor);
+
+ // Clean up
+ descriptor.postParse(stream);
} catch (Exception ex) {
Log.e(TAG, "Exception parsing USB descriptors.", ex);
}
-
- // Its OK to add the invalid descriptor as the postParse()
- // routine will mark it as invalid.
- mDescriptors.add(descriptor);
-
- // Clean up
- descriptor.postParse(stream);
}
}
}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 177759e..db49391 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -454,10 +454,6 @@
* @param conferenceableConnections The set of connections this connection can conference with.
*/
public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
- if (Objects.equals(mConferenceableConnections, conferenceableConnections)) {
- return;
- }
-
clearConferenceableList();
for (Connection c : conferenceableConnections) {
// If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0001d42..23db6ac 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -269,7 +269,9 @@
*
* @see SubscriptionManager#getSubscriptionPlans(int)
* @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
+ * @hide
*/
+ @SystemApi
public static final String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING =
"config_plans_package_override_string";
@@ -1034,6 +1036,26 @@
*/
public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET =
"carrier_default_actions_on_reset_string_array";
+
+ /**
+ * Defines carrier-specific actions which act upon
+ * com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+ * used for customization of the default carrier app
+ * Format:
+ * {
+ * "true : CARRIER_ACTION_IDX_1",
+ * "false: CARRIER_ACTION_IDX_2"
+ * }
+ * Where {@code true} is a boolean indicates default network available/unavailable
+ * Where {@code CARRIER_ACTION_IDX} is an integer defined in
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
+ * Example:
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils
+ * #CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER enable the app as the default URL handler}
+ * @hide
+ */
+ public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE =
+ "carrier_default_actions_on_default_network_available_string_array";
/**
* Defines a list of acceptable redirection url for default carrier app
* @hides
@@ -1366,17 +1388,6 @@
"notify_international_call_on_wfc_bool";
/**
- * Determine whether user edited tether APN (type dun) has effect
- * {@code false} - Default. APN with dun type in telephony database has no effect.
- *
- * {@code true} - DUN APN added/edited in ApnEditor will be used for tethering data call.
- *
- * @hide
- */
- public static final String KEY_EDITABLE_TETHER_APN_BOOL =
- "editable_tether_apn_bool";
-
- /**
* An array containing custom call forwarding number prefixes that will be blocked while the
* device is reporting that it is roaming. By default, there are no custom call
* forwarding prefixes and none of these numbers will be filtered. If one or more entries are
@@ -1396,11 +1407,7 @@
* <p>
* This setting may be still overridden by explicit user choice. By default,
* the platform value will be used.
- *
- * @deprecated replaced by
- * {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
*/
- @Deprecated
public static final String KEY_MONTHLY_DATA_CYCLE_DAY_INT =
"monthly_data_cycle_day_int";
@@ -1425,7 +1432,6 @@
* default data limit, if one exists, will be disabled. A user selected data limit will not be
* overridden.
*/
- @Deprecated
public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2;
/**
@@ -1438,11 +1444,7 @@
* <p>
* This setting may be overridden by explicit user choice. By default, the platform value
* will be used.
- *
- * @deprecated replaced by
- * {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
*/
- @Deprecated
public static final String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG =
"data_warning_threshold_bytes_long";
@@ -1456,11 +1458,7 @@
* <p>
* This setting may be overridden by explicit user choice. By default, the platform value
* will be used.
- *
- * @deprecated replaced by
- * {@link SubscriptionManager#setSubscriptionPlans(int, java.util.List)}
*/
- @Deprecated
public static final String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG =
"data_limit_threshold_bytes_long";
@@ -1734,9 +1732,10 @@
sDefaults.putString(KEY_CARRIER_SETUP_APP_STRING, "");
sDefaults.putStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
new String[]{
- "com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:" +
- "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED," +
- "com.android.internal.telephony.CARRIER_SIGNAL_RESET"
+ "com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED,"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_RESET,"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"
});
sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
@@ -1744,12 +1743,22 @@
// Default carrier app configurations
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY,
new String[]{
- "4, 1"
+ "9, 4, 1"
+ //9: CARRIER_ACTION_REGISTER_NETWORK_AVAIL
//4: CARRIER_ACTION_DISABLE_METERED_APNS
//1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
});
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET, new String[]{
- "6" //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+ "6, 8"
+ //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+ //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
+ });
+ sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE,
+ new String[] {
+ String.valueOf(false) + ": 7",
+ //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
+ String.valueOf(true) + ": 8"
+ //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
});
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
@@ -1782,7 +1791,6 @@
sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false);
- sDefaults.putBoolean(KEY_EDITABLE_TETHER_APN_BOOL, false);
sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY,
null);
sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 503bf82..88f4880 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
import android.content.Context;
@@ -31,14 +32,13 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
-
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
-
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -59,7 +59,7 @@
/** Base value for Dummy SUBSCRIPTION_ID's. */
/** FIXME: Remove DummySubId's, but for now have them map just below INVALID_SUBSCRIPTION_ID
- /** @hide */
+ /** @hide */
public static final int DUMMY_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
/** An invalid phone identifier */
@@ -368,7 +368,7 @@
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUB_DEFAULT_CHANGED_ACTION =
- "android.intent.action.SUB_DEFAULT_CHANGED";
+ "android.intent.action.SUB_DEFAULT_CHANGED";
/**
* Broadcast Action: The default subscription has changed. This has the following
@@ -621,7 +621,7 @@
}
if (result == null) {
- result = new ArrayList<SubscriptionInfo>();
+ result = new ArrayList<>();
}
return result;
}
@@ -1450,8 +1450,8 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- resultValue = iSub.getSubscriptionProperty(subId, propKey,
- context.getOpPackageName());
+ resultValue = iSub.getSubscriptionProperty(subId, propKey,
+ context.getOpPackageName());
}
} catch (RemoteException ex) {
// ignore it
@@ -1555,13 +1555,17 @@
* </ul>
*
* @param subId the subscriber this relationship applies to
+ * @hide
*/
+ @SystemApi
public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
final INetworkPolicyManager npm = INetworkPolicyManager.Stub
.asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
try {
- return Arrays.asList(npm.getSubscriptionPlans(subId,
- mContext.getOpPackageName()));
+ SubscriptionPlan[] subscriptionPlans =
+ npm.getSubscriptionPlans(subId, mContext.getOpPackageName());
+ return subscriptionPlans == null
+ ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1583,7 +1587,9 @@
* @param plans the list of plans. The first plan is always the primary and
* most important plan. Any additional plans are secondary and
* may not be displayed or used by decision making logic.
+ * @hide
*/
+ @SystemApi
public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
final INetworkPolicyManager npm = INetworkPolicyManager.Stub
.asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index c9419c5..265e3e7 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pair;
@@ -42,7 +43,9 @@
*
* @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
* @see SubscriptionManager#getSubscriptionPlans(int)
+ * @hide
*/
+@SystemApi
public final class SubscriptionPlan implements Parcelable {
/** {@hide} */
@IntDef(prefix = "LIMIT_BEHAVIOR_", value = {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 2e7b19a..6a9d00e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1654,8 +1654,7 @@
* @hide
*/
public String getNetworkCountryIso(int subId) {
- int phoneId = SubscriptionManager.getPhoneId(subId);
- return getNetworkCountryIsoForPhone(phoneId);
+ return getNetworkCountryIsoForPhone(getPhoneId(subId));
}
/**
@@ -1670,7 +1669,14 @@
*/
/** {@hide} */
public String getNetworkCountryIsoForPhone(int phoneId) {
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null)
+ return "";
+ return telephony.getNetworkCountryIsoForPhone(phoneId);
+ } catch (RemoteException ex) {
+ return "";
+ }
}
/** Network type is unknown */
@@ -6667,6 +6673,25 @@
}
/**
+ * Action set from carrier signalling broadcast receivers to start/stop reporting default
+ * network available events
+ * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * @param subId the subscription ID that this action applies to.
+ * @param report control start/stop reporting network status.
+ * @hide
+ */
+ public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.carrierActionReportDefaultNetworkStatus(subId, report);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#carrierActionReportDefaultNetworkStatus", e);
+ }
+ }
+
+ /**
* Get aggregated video call data usage since boot.
* Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
*
diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
index 831ab12..748092d 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
@@ -29,7 +29,7 @@
* by having one of the methods called on the {@link IImsCallSessionListener}.
* {@hide}
*/
-interface IImsCallSessionListener {
+oneway interface IImsCallSessionListener {
/**
* Notifies the result of the basic session operation (setup / terminate).
*/
diff --git a/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl b/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl
index d866ecb..6066f49 100644
--- a/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsEcbmListener.aidl
@@ -35,7 +35,7 @@
*
* {@hide}
*/
-interface IImsEcbmListener {
+oneway interface IImsEcbmListener {
/**
* Notifies the application when the device enters Emergency Callback Mode.
*/
diff --git a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
index 27b8fa1..1621967 100644
--- a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
@@ -23,7 +23,7 @@
*
* {@hide}
*/
-interface IImsExternalCallStateListener {
+oneway interface IImsExternalCallStateListener {
/**
* Notifies client when Dialog Event Package update is received
diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
index 98f8e0a..15f8726 100644
--- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
@@ -26,7 +26,7 @@
*
* {@hide}
*/
-interface IImsRegistrationListener {
+oneway interface IImsRegistrationListener {
/**
* Notifies the application when the device is connected to the IMS network.
*
diff --git a/telephony/java/com/android/ims/internal/IImsUtListener.aidl b/telephony/java/com/android/ims/internal/IImsUtListener.aidl
index 64166310..300273a 100644
--- a/telephony/java/com/android/ims/internal/IImsUtListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsUtListener.aidl
@@ -26,7 +26,7 @@
/**
* {@hide}
*/
-interface IImsUtListener {
+oneway interface IImsUtListener {
/**
* Notifies the result of the supplementary service configuration udpate.
*/
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index a0e5b7b..9262ec5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -377,6 +377,13 @@
Bundle getCellLocation(String callingPkg);
/**
+ * Returns the ISO country code equivalent of the current registered
+ * operator's MCC (Mobile Country Code).
+ * @see android.telephony.TelephonyManager#getNetworkCountryIso
+ */
+ String getNetworkCountryIsoForPhone(int phoneId);
+
+ /**
* Returns the neighboring cell information of the device.
*/
List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
@@ -1296,6 +1303,16 @@
void carrierActionSetRadioEnabled(int subId, boolean enabled);
/**
+ * Action set from carrier signalling broadcast receivers to start/stop reporting default
+ * network conditions.
+ * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * @param subId the subscription ID that this action applies to.
+ * @param report control start/stop reporting default network events.
+ * @hide
+ */
+ void carrierActionReportDefaultNetworkStatus(int subId, boolean report);
+
+ /**
* Get aggregated video call data usage since boot.
* Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
*
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 0343890..f29d993c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -447,6 +447,20 @@
"com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
/**
+ * <p>Broadcast Action: when system default network available/unavailable with
+ * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when
+ * other network becomes system default network, Wi-Fi for example.
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li>defaultNetworkAvailable</li><dd>A boolean indicates default network available.</dd>
+ * <li>subId</li><dd>Sub Id which associated the default data.</dd>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system. </p>
+ */
+ public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE =
+ "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+
+ /**
* <p>Broadcast Action: when framework reset all carrier actions on sim load or absent.
* intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app
* The intent will have the following extra values:</p>
@@ -465,7 +479,7 @@
public static final String EXTRA_APN_PROTO_KEY = "apnProto";
public static final String EXTRA_PCO_ID_KEY = "pcoId";
public static final String EXTRA_PCO_VALUE_KEY = "pcoValue";
-
+ public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable";
/**
* Broadcast action to trigger CI OMA-DM Session.
diff --git a/test-runner/api/android-test-mock-current.txt b/test-runner/api/android-test-mock-current.txt
index 4063ed7..93bbf6c 100644
--- a/test-runner/api/android-test-mock-current.txt
+++ b/test-runner/api/android-test-mock-current.txt
@@ -292,6 +292,7 @@
method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
method public int getMoveStatus(int);
method public java.lang.String getNameForUid(int);
+ method public java.lang.String[] getNamesForUids(int[]);
method public java.util.List<android.os.storage.VolumeInfo> getPackageCandidateVolumes(android.content.pm.ApplicationInfo);
method public android.os.storage.VolumeInfo getPackageCurrentVolume(android.content.pm.ApplicationInfo);
method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 3cb1f39..68fd825 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -321,6 +321,11 @@
throw new UnsupportedOperationException();
}
+ @Override
+ public String[] getNamesForUids(int uid[]) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* @hide - to match hiding in superclass
*/
diff --git a/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
new file mode 100644
index 0000000..73df9a0
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.graphics;
+
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+@SmallTest
+public class ColorUtilsTest {
+
+ @Test
+ public void calculateMinimumBackgroundAlpha_satisfiestContrast() {
+
+ int alpha = ColorUtils.calculateMinimumBackgroundAlpha(Color.WHITE, Color.BLACK, 4.5f);
+ assertTrue("Alpha doesn't need to be 255 to satisfy contrast", alpha < 255);
+
+ int worstCase = ColorUtils.blendARGB(Color.WHITE, Color.BLACK, alpha/255f);
+ worstCase = ColorUtils.setAlphaComponent(worstCase, 255);
+ double contrast = ColorUtils.calculateContrast(Color.WHITE, worstCase);
+ assertTrue("Blended color should satisfy contrast", contrast >= 4.5);
+
+ }
+}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index e3b06c8..7346f9f 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -21,10 +21,14 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
@@ -114,4 +118,45 @@
assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
}
+ @Test
+ public void testDescribeImmutableDifferences() {
+ NetworkCapabilities nc1;
+ NetworkCapabilities nc2;
+
+ // Transports changing
+ nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_CELLULAR);
+ nc2 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
+ assertNotEquals("", nc1.describeImmutableDifferences(nc2));
+ assertEquals("", nc1.describeImmutableDifferences(nc1));
+
+ // Mutable capability changing
+ nc1 = new NetworkCapabilities().addCapability(NET_CAPABILITY_VALIDATED);
+ nc2 = new NetworkCapabilities();
+ assertEquals("", nc1.describeImmutableDifferences(nc2));
+ assertEquals("", nc1.describeImmutableDifferences(nc1));
+
+ // NOT_METERED changing (http://b/63326103)
+ nc1 = new NetworkCapabilities()
+ .addCapability(NET_CAPABILITY_NOT_METERED)
+ .addCapability(NET_CAPABILITY_INTERNET);
+ nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET);
+ assertEquals("", nc1.describeImmutableDifferences(nc2));
+ assertEquals("", nc1.describeImmutableDifferences(nc1));
+
+ // Immutable capability changing
+ nc1 = new NetworkCapabilities()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET);
+ assertNotEquals("", nc1.describeImmutableDifferences(nc2));
+ assertEquals("", nc1.describeImmutableDifferences(nc1));
+
+ // Specifier changing
+ nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
+ nc2 = new NetworkCapabilities()
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(new StringNetworkSpecifier("specs"));
+ assertNotEquals("", nc1.describeImmutableDifferences(nc2));
+ assertEquals("", nc1.describeImmutableDifferences(nc1));
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index f201bc7..911347c 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -16,6 +16,16 @@
package com.android.server.connectivity;
+import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
@@ -37,15 +47,6 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.*;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
public class NetworkNotificationManagerTest extends TestCase {
static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
@@ -140,4 +141,47 @@
verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
}
+
+ @SmallTest
+ public void testDuplicatedNotificationsNoInternetThenSignIn() {
+ final int id = 101;
+ final String tag = NetworkNotificationManager.tagFor(id);
+
+ // Show first NO_INTERNET
+ mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
+ verify(mNotificationManager, times(1))
+ .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any());
+
+ // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET
+ mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
+ verify(mNotificationManager, times(1))
+ .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any());
+ verify(mNotificationManager, times(1))
+ .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
+
+ // Network disconnects
+ mManager.clearNotification(id);
+ verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
+ }
+
+ @SmallTest
+ public void testDuplicatedNotificationsSignInThenNoInternet() {
+ final int id = 101;
+ final String tag = NetworkNotificationManager.tagFor(id);
+
+ // Show first SIGN_IN
+ mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
+ verify(mNotificationManager, times(1))
+ .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
+ reset(mNotificationManager);
+
+ // NO_INTERNET arrives after, but is ignored.
+ mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
+ verify(mNotificationManager, never()).cancelAsUser(any(), anyInt(), any());
+ verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
+
+ // Network disconnects
+ mManager.clearNotification(id);
+ verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
+ }
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 9a37913..a5783a5 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -268,8 +268,7 @@
continue;
}
- if (!parser->element_namespace().empty() ||
- parser->element_name() != "resources") {
+ if (!parser->element_namespace().empty() || parser->element_name() != "resources") {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
<< "root element must be <resources>");
return false;
@@ -328,8 +327,7 @@
parsed_resource.comment = std::move(comment);
// Extract the product name if it exists.
- if (Maybe<StringPiece> maybe_product =
- xml::FindNonEmptyAttribute(parser, "product")) {
+ if (Maybe<StringPiece> maybe_product = xml::FindNonEmptyAttribute(parser, "product")) {
parsed_resource.product = maybe_product.value().to_string();
}
@@ -348,10 +346,8 @@
for (const ResourceName& stripped_resource : stripped_resources) {
if (!table_->FindResource(stripped_resource)) {
// Failed to find the resource.
- diag_->Error(DiagMessage(source_)
- << "resource '" << stripped_resource
- << "' "
- "was filtered out but no product variant remains");
+ diag_->Error(DiagMessage(source_) << "resource '" << stripped_resource
+ << "' was filtered out but no product variant remains");
error = true;
}
}
@@ -589,7 +585,7 @@
// This can only be a StyledString.
std::unique_ptr<StyledString> styled_string =
util::make_unique<StyledString>(table_->string_pool.MakeRef(
- style_string, StringPool::Context(StringPool::Context::kStylePriority, config_)));
+ style_string, StringPool::Context(StringPool::Context::kNormalPriority, config_)));
styled_string->untranslatable_sections = std::move(untranslatable_sections);
return std::move(styled_string);
}
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index d47a529..1683c64 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -117,7 +117,7 @@
StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
ASSERT_THAT(str, NotNull());
- EXPECT_THAT(*str->value->str, Eq("This is my aunt\u2019s fickle string"));
+ EXPECT_THAT(str->value->value, Eq("This is my aunt\u2019s fickle string"));
EXPECT_THAT(str->value->spans, SizeIs(2));
EXPECT_THAT(str->untranslatable_sections, IsEmpty());
@@ -190,7 +190,7 @@
StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
ASSERT_THAT(str, NotNull());
- EXPECT_THAT(*str->value->str, Eq("There are %1$d apples"));
+ EXPECT_THAT(str->value->value, Eq("There are %1$d apples"));
ASSERT_THAT(str->untranslatable_sections, SizeIs(1));
// We expect indices and lengths that span to include the whitespace
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 6e6a2ba..f193fe0 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -700,7 +700,7 @@
spans++;
}
return util::make_unique<StyledString>(dst_pool->MakeRef(
- style_str, StringPool::Context(StringPool::Context::kStylePriority, config)));
+ style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
} else {
if (type != ResourceType::kString && util::StartsWith(str, "res/")) {
// This must be a FileReference.
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 947e091..eb59175 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -253,10 +253,9 @@
}
void StyledString::Print(std::ostream* out) const {
- *out << "(styled string) \"" << *value->str << "\"";
+ *out << "(styled string) \"" << value->value << "\"";
for (const StringPool::Span& span : value->spans) {
- *out << " " << *span.name << ":" << span.first_char << ","
- << span.last_char;
+ *out << " " << *span.name << ":" << span.first_char << "," << span.last_char;
}
}
diff --git a/tools/aapt2/StringPool.cpp b/tools/aapt2/StringPool.cpp
index 57da5f0..705b1ab 100644
--- a/tools/aapt2/StringPool.cpp
+++ b/tools/aapt2/StringPool.cpp
@@ -27,7 +27,7 @@
#include "util/BigBuffer.h"
#include "util/Util.h"
-using android::StringPiece;
+using ::android::StringPiece;
namespace aapt {
@@ -75,9 +75,14 @@
return &entry_->value;
}
-const std::string& StringPool::Ref::operator*() const { return entry_->value; }
+const std::string& StringPool::Ref::operator*() const {
+ return entry_->value;
+}
-size_t StringPool::Ref::index() const { return entry_->index; }
+size_t StringPool::Ref::index() const {
+ // Account for the styles, which *always* come first.
+ return entry_->pool_->styles_.size() + entry_->index_;
+}
const StringPool::Context& StringPool::Ref::GetContext() const {
return entry_->context;
@@ -104,8 +109,7 @@
}
}
-StringPool::StyleRef& StringPool::StyleRef::operator=(
- const StringPool::StyleRef& rhs) {
+StringPool::StyleRef& StringPool::StyleRef::operator=(const StringPool::StyleRef& rhs) {
if (rhs.entry_ != nullptr) {
rhs.entry_->ref_++;
}
@@ -118,7 +122,7 @@
}
bool StringPool::StyleRef::operator==(const StyleRef& rhs) const {
- if (entry_->str != rhs.entry_->str) {
+ if (entry_->value != rhs.entry_->value) {
return false;
}
@@ -137,7 +141,9 @@
return true;
}
-bool StringPool::StyleRef::operator!=(const StyleRef& rhs) const { return !operator==(rhs); }
+bool StringPool::StyleRef::operator!=(const StyleRef& rhs) const {
+ return !operator==(rhs);
+}
const StringPool::StyleEntry* StringPool::StyleRef::operator->() const {
return entry_;
@@ -147,23 +153,24 @@
return *entry_;
}
-size_t StringPool::StyleRef::index() const { return entry_->str.index(); }
+size_t StringPool::StyleRef::index() const {
+ return entry_->index_;
+}
const StringPool::Context& StringPool::StyleRef::GetContext() const {
- return entry_->str.GetContext();
+ return entry_->context;
}
StringPool::Ref StringPool::MakeRef(const StringPiece& str) {
return MakeRefImpl(str, Context{}, true);
}
-StringPool::Ref StringPool::MakeRef(const StringPiece& str,
- const Context& context) {
+StringPool::Ref StringPool::MakeRef(const StringPiece& str, const Context& context) {
return MakeRefImpl(str, context, true);
}
-StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str,
- const Context& context, bool unique) {
+StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str, const Context& context,
+ bool unique) {
if (unique) {
auto iter = indexed_strings_.find(str);
if (iter != std::end(indexed_strings_)) {
@@ -171,82 +178,87 @@
}
}
- Entry* entry = new Entry();
+ std::unique_ptr<Entry> entry(new Entry());
entry->value = str.to_string();
entry->context = context;
- entry->index = strings_.size();
+ entry->index_ = strings_.size();
entry->ref_ = 0;
- strings_.emplace_back(entry);
- indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
- return Ref(entry);
+ entry->pool_ = this;
+
+ Entry* borrow = entry.get();
+ strings_.emplace_back(std::move(entry));
+ indexed_strings_.insert(std::make_pair(StringPiece(borrow->value), borrow));
+ return Ref(borrow);
}
StringPool::StyleRef StringPool::MakeRef(const StyleString& str) {
return MakeRef(str, Context{});
}
-StringPool::StyleRef StringPool::MakeRef(const StyleString& str,
- const Context& context) {
- Entry* entry = new Entry();
+StringPool::StyleRef StringPool::MakeRef(const StyleString& str, const Context& context) {
+ std::unique_ptr<StyleEntry> entry(new StyleEntry());
entry->value = str.str;
entry->context = context;
- entry->index = strings_.size();
+ entry->index_ = styles_.size();
entry->ref_ = 0;
- strings_.emplace_back(entry);
- indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
-
- StyleEntry* style_entry = new StyleEntry();
- style_entry->str = Ref(entry);
for (const aapt::Span& span : str.spans) {
- style_entry->spans.emplace_back(
- Span{MakeRef(span.name), span.first_char, span.last_char});
+ entry->spans.emplace_back(Span{MakeRef(span.name), span.first_char, span.last_char});
}
- style_entry->ref_ = 0;
- styles_.emplace_back(style_entry);
- return StyleRef(style_entry);
+
+ StyleEntry* borrow = entry.get();
+ styles_.emplace_back(std::move(entry));
+ return StyleRef(borrow);
}
StringPool::StyleRef StringPool::MakeRef(const StyleRef& ref) {
- Entry* entry = new Entry();
- entry->value = *ref.entry_->str;
- entry->context = ref.entry_->str.entry_->context;
- entry->index = strings_.size();
+ std::unique_ptr<StyleEntry> entry(new StyleEntry());
+ entry->value = ref.entry_->value;
+ entry->context = ref.entry_->context;
+ entry->index_ = styles_.size();
entry->ref_ = 0;
- strings_.emplace_back(entry);
- indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry));
-
- StyleEntry* style_entry = new StyleEntry();
- style_entry->str = Ref(entry);
for (const Span& span : ref.entry_->spans) {
- style_entry->spans.emplace_back(
- Span{MakeRef(*span.name), span.first_char, span.last_char});
+ entry->spans.emplace_back(Span{MakeRef(*span.name), span.first_char, span.last_char});
}
- style_entry->ref_ = 0;
- styles_.emplace_back(style_entry);
- return StyleRef(style_entry);
+
+ StyleEntry* borrow = entry.get();
+ styles_.emplace_back(std::move(entry));
+ return StyleRef(borrow);
+}
+
+void StringPool::ReAssignIndices() {
+ // Assign the style indices.
+ const size_t style_len = styles_.size();
+ for (size_t index = 0; index < style_len; index++) {
+ styles_[index]->index_ = index;
+ }
+
+ // Assign the string indices.
+ const size_t string_len = strings_.size();
+ for (size_t index = 0; index < string_len; index++) {
+ strings_[index]->index_ = index;
+ }
}
void StringPool::Merge(StringPool&& pool) {
- indexed_strings_.insert(pool.indexed_strings_.begin(),
- pool.indexed_strings_.end());
- pool.indexed_strings_.clear();
- std::move(pool.strings_.begin(), pool.strings_.end(),
- std::back_inserter(strings_));
- pool.strings_.clear();
- std::move(pool.styles_.begin(), pool.styles_.end(),
- std::back_inserter(styles_));
- pool.styles_.clear();
-
- // Assign the indices.
- const size_t len = strings_.size();
- for (size_t index = 0; index < len; index++) {
- strings_[index]->index = index;
+ // First, change the owning pool for the incoming strings.
+ for (std::unique_ptr<Entry>& entry : pool.strings_) {
+ entry->pool_ = this;
}
+
+ // Now move the styles, strings, and indices over.
+ std::move(pool.styles_.begin(), pool.styles_.end(), std::back_inserter(styles_));
+ pool.styles_.clear();
+ std::move(pool.strings_.begin(), pool.strings_.end(), std::back_inserter(strings_));
+ pool.strings_.clear();
+ indexed_strings_.insert(pool.indexed_strings_.begin(), pool.indexed_strings_.end());
+ pool.indexed_strings_.clear();
+
+ ReAssignIndices();
}
-void StringPool::HintWillAdd(size_t stringCount, size_t styleCount) {
- strings_.reserve(strings_.size() + stringCount);
- styles_.reserve(styles_.size() + styleCount);
+void StringPool::HintWillAdd(size_t string_count, size_t style_count) {
+ strings_.reserve(strings_.size() + string_count);
+ styles_.reserve(styles_.size() + style_count);
}
void StringPool::Prune() {
@@ -262,47 +274,42 @@
auto end_iter2 =
std::remove_if(strings_.begin(), strings_.end(),
- [](const std::unique_ptr<Entry>& entry) -> bool {
- return entry->ref_ <= 0;
- });
+ [](const std::unique_ptr<Entry>& entry) -> bool { return entry->ref_ <= 0; });
+ auto end_iter3 = std::remove_if(
+ styles_.begin(), styles_.end(),
+ [](const std::unique_ptr<StyleEntry>& entry) -> bool { return entry->ref_ <= 0; });
- auto end_iter3 =
- std::remove_if(styles_.begin(), styles_.end(),
- [](const std::unique_ptr<StyleEntry>& entry) -> bool {
- return entry->ref_ <= 0;
- });
-
- // Remove the entries at the end or else we'll be accessing
- // a deleted string from the StyleEntry.
+ // Remove the entries at the end or else we'll be accessing a deleted string from the StyleEntry.
strings_.erase(end_iter2, strings_.end());
styles_.erase(end_iter3, styles_.end());
- // Reassign the indices.
- const size_t len = strings_.size();
- for (size_t index = 0; index < len; index++) {
- strings_[index]->index = index;
+ ReAssignIndices();
+}
+
+template <typename E>
+static void SortEntries(
+ std::vector<std::unique_ptr<E>>& entries,
+ const std::function<int(const StringPool::Context&, const StringPool::Context&)>& cmp) {
+ using UEntry = std::unique_ptr<E>;
+
+ if (cmp != nullptr) {
+ std::sort(entries.begin(), entries.end(), [&cmp](const UEntry& a, const UEntry& b) -> bool {
+ int r = cmp(a->context, b->context);
+ if (r == 0) {
+ r = a->value.compare(b->value);
+ }
+ return r < 0;
+ });
+ } else {
+ std::sort(entries.begin(), entries.end(),
+ [](const UEntry& a, const UEntry& b) -> bool { return a->value < b->value; });
}
}
-void StringPool::Sort(
- const std::function<bool(const Entry&, const Entry&)>& cmp) {
- std::sort(
- strings_.begin(), strings_.end(),
- [&cmp](const std::unique_ptr<Entry>& a,
- const std::unique_ptr<Entry>& b) -> bool { return cmp(*a, *b); });
-
- // Assign the indices.
- const size_t len = strings_.size();
- for (size_t index = 0; index < len; index++) {
- strings_[index]->index = index;
- }
-
- // Reorder the styles.
- std::sort(styles_.begin(), styles_.end(),
- [](const std::unique_ptr<StyleEntry>& lhs,
- const std::unique_ptr<StyleEntry>& rhs) -> bool {
- return lhs->str.index() < rhs->str.index();
- });
+void StringPool::Sort(const std::function<int(const Context&, const Context&)>& cmp) {
+ SortEntries(styles_, cmp);
+ SortEntries(strings_, cmp);
+ ReAssignIndices();
}
template <typename T>
@@ -327,60 +334,31 @@
return length > kMaxSize ? 2 : 1;
}
-bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8) {
- const size_t start_index = out->size();
- android::ResStringPool_header* header =
- out->NextBlock<android::ResStringPool_header>();
- header->header.type = android::RES_STRING_POOL_TYPE;
- header->header.headerSize = sizeof(*header);
- header->stringCount = pool.size();
+static void EncodeString(const std::string& str, const bool utf8, BigBuffer* out) {
if (utf8) {
- header->flags |= android::ResStringPool_header::UTF8_FLAG;
- }
+ const std::string& encoded = str;
+ const ssize_t utf16_length =
+ utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str.data()), str.size());
+ CHECK(utf16_length >= 0);
- uint32_t* indices =
- pool.size() != 0 ? out->NextBlock<uint32_t>(pool.size()) : nullptr;
+ const size_t total_size = EncodedLengthUnits<char>(utf16_length) +
+ EncodedLengthUnits<char>(encoded.length()) + encoded.size() + 1;
- uint32_t* style_indices = nullptr;
- if (!pool.styles_.empty()) {
- header->styleCount = pool.styles_.back()->str.index() + 1;
- style_indices = out->NextBlock<uint32_t>(header->styleCount);
- }
+ char* data = out->NextBlock<char>(total_size);
- const size_t before_strings_index = out->size();
- header->stringsStart = before_strings_index - start_index;
+ // First encode the UTF16 string length.
+ data = EncodeLength(data, utf16_length);
- for (const auto& entry : pool) {
- *indices = out->size() - before_strings_index;
- indices++;
-
- if (utf8) {
- const std::string& encoded = entry->value;
- const ssize_t utf16_length = utf8_to_utf16_length(
- reinterpret_cast<const uint8_t*>(entry->value.data()),
- entry->value.size());
- CHECK(utf16_length >= 0);
-
- const size_t total_size = EncodedLengthUnits<char>(utf16_length) +
- EncodedLengthUnits<char>(encoded.length()) +
- encoded.size() + 1;
-
- char* data = out->NextBlock<char>(total_size);
-
- // First encode the UTF16 string length.
- data = EncodeLength(data, utf16_length);
-
- // Now encode the size of the real UTF8 string.
- data = EncodeLength(data, encoded.length());
- strncpy(data, encoded.data(), encoded.size());
+ // Now encode the size of the real UTF8 string.
+ data = EncodeLength(data, encoded.length());
+ strncpy(data, encoded.data(), encoded.size());
} else {
- const std::u16string encoded = util::Utf8ToUtf16(entry->value);
+ const std::u16string encoded = util::Utf8ToUtf16(str);
const ssize_t utf16_length = encoded.size();
// Total number of 16-bit words to write.
- const size_t total_size =
- EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1;
+ const size_t total_size = EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1;
char16_t* data = out->NextBlock<char16_t>(total_size);
@@ -395,31 +373,55 @@
// The null-terminating character is already here due to the block of data
// being set to 0s on allocation.
}
+}
+
+bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8) {
+ const size_t start_index = out->size();
+ android::ResStringPool_header* header = out->NextBlock<android::ResStringPool_header>();
+ header->header.type = util::HostToDevice16(android::RES_STRING_POOL_TYPE);
+ header->header.headerSize = util::HostToDevice16(sizeof(*header));
+ header->stringCount = util::HostToDevice32(pool.size());
+ header->styleCount = util::HostToDevice32(pool.styles_.size());
+ if (utf8) {
+ header->flags |= android::ResStringPool_header::UTF8_FLAG;
+ }
+
+ uint32_t* indices = pool.size() != 0 ? out->NextBlock<uint32_t>(pool.size()) : nullptr;
+ uint32_t* style_indices =
+ pool.styles_.size() != 0 ? out->NextBlock<uint32_t>(pool.styles_.size()) : nullptr;
+
+ const size_t before_strings_index = out->size();
+ header->stringsStart = before_strings_index - start_index;
+
+ // Styles always come first.
+ for (const std::unique_ptr<StyleEntry>& entry : pool.styles_) {
+ *indices++ = out->size() - before_strings_index;
+ EncodeString(entry->value, utf8, out);
+ }
+
+ for (const std::unique_ptr<Entry>& entry : pool.strings_) {
+ *indices++ = out->size() - before_strings_index;
+ EncodeString(entry->value, utf8, out);
}
out->Align4();
- if (!pool.styles_.empty()) {
+ if (style_indices != nullptr) {
const size_t before_styles_index = out->size();
- header->stylesStart = before_styles_index - start_index;
+ header->stylesStart = util::HostToDevice32(before_styles_index - start_index);
- size_t current_index = 0;
- for (const auto& entry : pool.styles_) {
- while (entry->str.index() > current_index) {
- style_indices[current_index++] = out->size() - before_styles_index;
+ for (const std::unique_ptr<StyleEntry>& entry : pool.styles_) {
+ *style_indices++ = out->size() - before_styles_index;
- uint32_t* span_offset = out->NextBlock<uint32_t>();
- *span_offset = android::ResStringPool_span::END;
- }
- style_indices[current_index++] = out->size() - before_styles_index;
-
- android::ResStringPool_span* span =
- out->NextBlock<android::ResStringPool_span>(entry->spans.size());
- for (const auto& s : entry->spans) {
- span->name.index = s.name.index();
- span->firstChar = s.first_char;
- span->lastChar = s.last_char;
- span++;
+ if (!entry->spans.empty()) {
+ android::ResStringPool_span* span =
+ out->NextBlock<android::ResStringPool_span>(entry->spans.size());
+ for (const Span& s : entry->spans) {
+ span->name.index = util::HostToDevice32(s.name.index());
+ span->firstChar = util::HostToDevice32(s.first_char);
+ span->lastChar = util::HostToDevice32(s.last_char);
+ span++;
+ }
}
uint32_t* spanEnd = out->NextBlock<uint32_t>();
@@ -436,7 +438,7 @@
memset(padding, 0xff, padding_length);
out->Align4();
}
- header->header.size = out->size() - start_index;
+ header->header.size = util::HostToDevice32(out->size() - start_index);
return true;
}
diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h
index d1232a2..8350d0d 100644
--- a/tools/aapt2/StringPool.h
+++ b/tools/aapt2/StringPool.h
@@ -42,12 +42,16 @@
std::vector<Span> spans;
};
+// A StringPool for storing the value of String and StyledString resources.
+// Styles and Strings are stored separately, since the runtime variant of this
+// class -- ResStringPool -- requires that styled strings *always* appear first, since their
+// style data is stored as an array indexed by the same indices as the main string pool array.
+// Otherwise, the style data array would have to be sparse and take up more space.
class StringPool {
public:
class Context {
public:
enum : uint32_t {
- kStylePriority = 0u,
kHighPriority = 1u,
kNormalPriority = 0x7fffffffu,
kLowPriority = 0xffffffffu,
@@ -58,8 +62,8 @@
Context() = default;
Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
explicit Context(uint32_t p) : priority(p) {}
- explicit Context(const ConfigDescription& c)
- : priority(kNormalPriority), config(c) {}
+ explicit Context(const ConfigDescription& c) : priority(kNormalPriority), config(c) {
+ }
};
class Entry;
@@ -116,13 +120,14 @@
public:
std::string value;
Context context;
- size_t index;
private:
friend class StringPool;
friend class Ref;
+ size_t index_;
int ref_;
+ const StringPool* pool_;
};
struct Span {
@@ -133,18 +138,18 @@
class StyleEntry {
public:
- Ref str;
+ std::string value;
+ Context context;
std::vector<Span> spans;
private:
friend class StringPool;
friend class StyleRef;
+ size_t index_;
int ref_;
};
- using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
-
static bool FlattenUtf8(BigBuffer* out, const StringPool& pool);
static bool FlattenUtf16(BigBuffer* out, const StringPool& pool);
@@ -152,92 +157,61 @@
StringPool(StringPool&&) = default;
StringPool& operator=(StringPool&&) = default;
- /**
- * Adds a string to the pool, unless it already exists. Returns
- * a reference to the string in the pool.
- */
+ // Adds a string to the pool, unless it already exists. Returns a reference to the string in the
+ // pool.
Ref MakeRef(const android::StringPiece& str);
- /**
- * Adds a string to the pool, unless it already exists, with a context
- * object that can be used when sorting the string pool. Returns
- * a reference to the string in the pool.
- */
+ // Adds a string to the pool, unless it already exists, with a context object that can be used
+ // when sorting the string pool. Returns a reference to the string in the pool.
Ref MakeRef(const android::StringPiece& str, const Context& context);
- /**
- * Adds a style to the string pool and returns a reference to it.
- */
+ // Adds a style to the string pool and returns a reference to it.
StyleRef MakeRef(const StyleString& str);
- /**
- * Adds a style to the string pool with a context object that
- * can be used when sorting the string pool. Returns a reference
- * to the style in the string pool.
- */
+ // Adds a style to the string pool with a context object that can be used when sorting the string
+ // pool. Returns a reference to the style in the string pool.
StyleRef MakeRef(const StyleString& str, const Context& context);
- /**
- * Adds a style from another string pool. Returns a reference to the
- * style in the string pool.
- */
+ // Adds a style from another string pool. Returns a reference to the style in the string pool.
StyleRef MakeRef(const StyleRef& ref);
- /**
- * Moves pool into this one without coalescing strings. When this
- * function returns, pool will be empty.
- */
+ // Moves pool into this one without coalescing strings. When this function returns, pool will be
+ // empty.
void Merge(StringPool&& pool);
- /**
- * Returns the number of strings in the table.
- */
- inline size_t size() const;
+ inline const std::vector<std::unique_ptr<Entry>>& strings() const {
+ return strings_;
+ }
- /**
- * Reserves space for strings and styles as an optimization.
- */
+ // Returns the number of strings in the table.
+ inline size_t size() const {
+ return styles_.size() + strings_.size();
+ }
+
+ // Reserves space for strings and styles as an optimization.
void HintWillAdd(size_t string_count, size_t style_count);
- /**
- * Sorts the strings according to some comparison function.
- */
- void Sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
+ // Sorts the strings according to their Context using some comparison function.
+ // Equal Contexts are further sorted by string value, lexicographically.
+ // If no comparison function is provided, values are only sorted lexicographically.
+ void Sort(const std::function<int(const Context&, const Context&)>& cmp = nullptr);
- /**
- * Removes any strings that have no references.
- */
+ // Removes any strings that have no references.
void Prune();
private:
DISALLOW_COPY_AND_ASSIGN(StringPool);
- friend const_iterator begin(const StringPool& pool);
- friend const_iterator end(const StringPool& pool);
-
static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8);
Ref MakeRefImpl(const android::StringPiece& str, const Context& context, bool unique);
+ void ReAssignIndices();
std::vector<std::unique_ptr<Entry>> strings_;
std::vector<std::unique_ptr<StyleEntry>> styles_;
std::unordered_multimap<android::StringPiece, Entry*> indexed_strings_;
};
-//
-// Inline implementation
-//
-
-inline size_t StringPool::size() const { return strings_.size(); }
-
-inline StringPool::const_iterator begin(const StringPool& pool) {
- return pool.strings_.begin();
-}
-
-inline StringPool::const_iterator end(const StringPool& pool) {
- return pool.strings_.end();
-}
-
} // namespace aapt
#endif // AAPT_STRING_POOL_H
diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp
index f64a8cf..b1e5ce2 100644
--- a/tools/aapt2/StringPool_test.cpp
+++ b/tools/aapt2/StringPool_test.cpp
@@ -23,8 +23,12 @@
#include "test/Test.h"
#include "util/Util.h"
-using android::StringPiece;
-using android::StringPiece16;
+using ::android::StringPiece;
+using ::android::StringPiece16;
+using ::testing::Eq;
+using ::testing::Ne;
+using ::testing::NotNull;
+using ::testing::Pointee;
namespace aapt {
@@ -32,129 +36,127 @@
StringPool pool;
StringPool::Ref ref = pool.MakeRef("wut");
- EXPECT_EQ(*ref, "wut");
+ EXPECT_THAT(*ref, Eq("wut"));
}
TEST(StringPoolTest, InsertTwoUniqueStrings) {
StringPool pool;
- StringPool::Ref ref = pool.MakeRef("wut");
- StringPool::Ref ref2 = pool.MakeRef("hey");
+ StringPool::Ref ref_a = pool.MakeRef("wut");
+ StringPool::Ref ref_b = pool.MakeRef("hey");
- EXPECT_EQ(*ref, "wut");
- EXPECT_EQ(*ref2, "hey");
+ EXPECT_THAT(*ref_a, Eq("wut"));
+ EXPECT_THAT(*ref_b, Eq("hey"));
}
TEST(StringPoolTest, DoNotInsertNewDuplicateString) {
StringPool pool;
- StringPool::Ref ref = pool.MakeRef("wut");
- StringPool::Ref ref2 = pool.MakeRef("wut");
+ StringPool::Ref ref_a = pool.MakeRef("wut");
+ StringPool::Ref ref_b = pool.MakeRef("wut");
- EXPECT_EQ(*ref, "wut");
- EXPECT_EQ(*ref2, "wut");
- EXPECT_EQ(1u, pool.size());
+ EXPECT_THAT(*ref_a, Eq("wut"));
+ EXPECT_THAT(*ref_b, Eq("wut"));
+ EXPECT_THAT(pool.size(), Eq(1u));
}
TEST(StringPoolTest, MaintainInsertionOrderIndex) {
StringPool pool;
- StringPool::Ref ref = pool.MakeRef("z");
- StringPool::Ref ref2 = pool.MakeRef("a");
- StringPool::Ref ref3 = pool.MakeRef("m");
+ StringPool::Ref ref_a = pool.MakeRef("z");
+ StringPool::Ref ref_b = pool.MakeRef("a");
+ StringPool::Ref ref_c = pool.MakeRef("m");
- EXPECT_EQ(0u, ref.index());
- EXPECT_EQ(1u, ref2.index());
- EXPECT_EQ(2u, ref3.index());
+ EXPECT_THAT(ref_a.index(), Eq(0u));
+ EXPECT_THAT(ref_b.index(), Eq(1u));
+ EXPECT_THAT(ref_c.index(), Eq(2u));
}
TEST(StringPoolTest, PruneStringsWithNoReferences) {
StringPool pool;
- StringPool::Ref refA = pool.MakeRef("foo");
- {
- StringPool::Ref ref = pool.MakeRef("wut");
- EXPECT_EQ(*ref, "wut");
- EXPECT_EQ(2u, pool.size());
- }
- StringPool::Ref refB = pool.MakeRef("bar");
+ StringPool::Ref ref_a = pool.MakeRef("foo");
- EXPECT_EQ(3u, pool.size());
+ {
+ StringPool::Ref ref_b = pool.MakeRef("wut");
+ EXPECT_THAT(*ref_b, Eq("wut"));
+ EXPECT_THAT(pool.size(), Eq(2u));
+ pool.Prune();
+ EXPECT_THAT(pool.size(), Eq(2u));
+ }
+ EXPECT_THAT(pool.size(), Eq(2u));
+
+ {
+ StringPool::Ref ref_c = pool.MakeRef("bar");
+ EXPECT_THAT(pool.size(), Eq(3u));
+
+ pool.Prune();
+ EXPECT_THAT(pool.size(), Eq(2u));
+ }
+ EXPECT_THAT(pool.size(), Eq(2u));
+
pool.Prune();
- EXPECT_EQ(2u, pool.size());
- StringPool::const_iterator iter = begin(pool);
- EXPECT_EQ((*iter)->value, "foo");
- EXPECT_LT((*iter)->index, 2u);
- ++iter;
- EXPECT_EQ((*iter)->value, "bar");
- EXPECT_LT((*iter)->index, 2u);
+ EXPECT_THAT(pool.size(), Eq(1u));
}
-TEST(StringPoolTest, SortAndMaintainIndexesInReferences) {
+TEST(StringPoolTest, SortAndMaintainIndexesInStringReferences) {
StringPool pool;
- StringPool::Ref ref = pool.MakeRef("z");
- StringPool::StyleRef ref2 = pool.MakeRef(StyleString{{"a"}});
- StringPool::Ref ref3 = pool.MakeRef("m");
+ StringPool::Ref ref_a = pool.MakeRef("z");
+ StringPool::Ref ref_b = pool.MakeRef("a");
+ StringPool::Ref ref_c = pool.MakeRef("m");
- EXPECT_EQ(*ref, "z");
- EXPECT_EQ(0u, ref.index());
+ EXPECT_THAT(*ref_a, Eq("z"));
+ EXPECT_THAT(ref_a.index(), Eq(0u));
- EXPECT_EQ(*(ref2->str), "a");
- EXPECT_EQ(1u, ref2.index());
+ EXPECT_THAT(*ref_b, Eq("a"));
+ EXPECT_THAT(ref_b.index(), Eq(1u));
- EXPECT_EQ(*ref3, "m");
- EXPECT_EQ(2u, ref3.index());
+ EXPECT_THAT(*ref_c, Eq("m"));
+ EXPECT_THAT(ref_c.index(), Eq(2u));
- pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
- return a.value < b.value;
- });
+ pool.Sort();
- EXPECT_EQ(*ref, "z");
- EXPECT_EQ(2u, ref.index());
+ EXPECT_THAT(*ref_a, Eq("z"));
+ EXPECT_THAT(ref_a.index(), Eq(2u));
- EXPECT_EQ(*(ref2->str), "a");
- EXPECT_EQ(0u, ref2.index());
+ EXPECT_THAT(*ref_b, Eq("a"));
+ EXPECT_THAT(ref_b.index(), Eq(0u));
- EXPECT_EQ(*ref3, "m");
- EXPECT_EQ(1u, ref3.index());
+ EXPECT_THAT(*ref_c, Eq("m"));
+ EXPECT_THAT(ref_c.index(), Eq(1u));
}
TEST(StringPoolTest, SortAndStillDedupe) {
StringPool pool;
- StringPool::Ref ref = pool.MakeRef("z");
- StringPool::Ref ref2 = pool.MakeRef("a");
- StringPool::Ref ref3 = pool.MakeRef("m");
+ StringPool::Ref ref_a = pool.MakeRef("z");
+ StringPool::Ref ref_b = pool.MakeRef("a");
+ StringPool::Ref ref_c = pool.MakeRef("m");
- pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
- return a.value < b.value;
- });
+ pool.Sort();
- StringPool::Ref ref4 = pool.MakeRef("z");
- StringPool::Ref ref5 = pool.MakeRef("a");
- StringPool::Ref ref6 = pool.MakeRef("m");
+ StringPool::Ref ref_d = pool.MakeRef("z");
+ StringPool::Ref ref_e = pool.MakeRef("a");
+ StringPool::Ref ref_f = pool.MakeRef("m");
- EXPECT_EQ(ref4.index(), ref.index());
- EXPECT_EQ(ref5.index(), ref2.index());
- EXPECT_EQ(ref6.index(), ref3.index());
+ EXPECT_THAT(ref_d.index(), Eq(ref_a.index()));
+ EXPECT_THAT(ref_e.index(), Eq(ref_b.index()));
+ EXPECT_THAT(ref_f.index(), Eq(ref_c.index()));
}
TEST(StringPoolTest, AddStyles) {
StringPool pool;
- StyleString str{{"android"}, {Span{{"b"}, 2, 6}}};
-
- StringPool::StyleRef ref = pool.MakeRef(str);
-
- EXPECT_EQ(0u, ref.index());
- EXPECT_EQ(std::string("android"), *(ref->str));
- ASSERT_EQ(1u, ref->spans.size());
+ StringPool::StyleRef ref = pool.MakeRef(StyleString{{"android"}, {Span{{"b"}, 2, 6}}});
+ EXPECT_THAT(ref.index(), Eq(0u));
+ EXPECT_THAT(ref->value, Eq("android"));
+ ASSERT_THAT(ref->spans.size(), Eq(1u));
const StringPool::Span& span = ref->spans.front();
- EXPECT_EQ(*(span.name), "b");
- EXPECT_EQ(2u, span.first_char);
- EXPECT_EQ(6u, span.last_char);
+ EXPECT_THAT(*span.name, Eq("b"));
+ EXPECT_THAT(span.first_char, Eq(2u));
+ EXPECT_THAT(span.last_char, Eq(6u));
}
TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
@@ -163,9 +165,25 @@
StringPool::Ref ref = pool.MakeRef("android");
StyleString str{{"android"}};
- StringPool::StyleRef styleRef = pool.MakeRef(str);
+ StringPool::StyleRef style_ref = pool.MakeRef(StyleString{{"android"}});
- EXPECT_NE(ref.index(), styleRef.index());
+ EXPECT_THAT(ref.index(), Ne(style_ref.index()));
+}
+
+TEST(StringPoolTest, StylesAndStringsAreSeparateAfterSorting) {
+ StringPool pool;
+
+ StringPool::StyleRef ref_a = pool.MakeRef(StyleString{{"beta"}});
+ StringPool::Ref ref_b = pool.MakeRef("alpha");
+ StringPool::StyleRef ref_c = pool.MakeRef(StyleString{{"alpha"}});
+
+ EXPECT_THAT(ref_b.index(), Ne(ref_c.index()));
+
+ pool.Sort();
+
+ EXPECT_THAT(ref_c.index(), Eq(0u));
+ EXPECT_THAT(ref_a.index(), Eq(1u));
+ EXPECT_THAT(ref_b.index(), Eq(2u));
}
TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
@@ -177,7 +195,7 @@
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
ResStringPool test;
- ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
+ ASSERT_THAT(test.setTo(data.get(), buffer.size()), Eq(NO_ERROR));
}
TEST(StringPoolTest, FlattenOddCharactersUtf16) {
@@ -193,9 +211,9 @@
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
size_t len = 0;
const char16_t* str = test.stringAt(0, &len);
- EXPECT_EQ(1u, len);
- EXPECT_EQ(u'\u093f', *str);
- EXPECT_EQ(0u, str[1]);
+ EXPECT_THAT(len, Eq(1u));
+ EXPECT_THAT(str, Pointee(Eq(u'\u093f')));
+ EXPECT_THAT(str[1], Eq(0u));
}
constexpr const char* sLongString =
@@ -210,18 +228,20 @@
StringPool pool;
- StringPool::Ref ref1 = pool.MakeRef("hello");
- StringPool::Ref ref2 = pool.MakeRef("goodbye");
- StringPool::Ref ref3 = pool.MakeRef(sLongString);
- StringPool::Ref ref4 = pool.MakeRef("");
- StringPool::StyleRef ref5 = pool.MakeRef(
- StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}});
+ StringPool::Ref ref_a = pool.MakeRef("hello");
+ StringPool::Ref ref_b = pool.MakeRef("goodbye");
+ StringPool::Ref ref_c = pool.MakeRef(sLongString);
+ StringPool::Ref ref_d = pool.MakeRef("");
+ StringPool::StyleRef ref_e =
+ pool.MakeRef(StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}});
- EXPECT_EQ(0u, ref1.index());
- EXPECT_EQ(1u, ref2.index());
- EXPECT_EQ(2u, ref3.index());
- EXPECT_EQ(3u, ref4.index());
- EXPECT_EQ(4u, ref5.index());
+ // Styles are always first.
+ EXPECT_THAT(ref_e.index(), Eq(0u));
+
+ EXPECT_THAT(ref_a.index(), Eq(1u));
+ EXPECT_THAT(ref_b.index(), Eq(2u));
+ EXPECT_THAT(ref_c.index(), Eq(3u));
+ EXPECT_THAT(ref_d.index(), Eq(4u));
BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)};
StringPool::FlattenUtf8(&buffers[0], pool);
@@ -234,38 +254,37 @@
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
- EXPECT_EQ(std::string("hello"), util::GetString(test, 0));
- EXPECT_EQ(StringPiece16(u"hello"), util::GetString16(test, 0));
+ EXPECT_THAT(util::GetString(test, 1), Eq("hello"));
+ EXPECT_THAT(util::GetString16(test, 1), Eq(u"hello"));
- EXPECT_EQ(std::string("goodbye"), util::GetString(test, 1));
- EXPECT_EQ(StringPiece16(u"goodbye"), util::GetString16(test, 1));
+ EXPECT_THAT(util::GetString(test, 2), Eq("goodbye"));
+ EXPECT_THAT(util::GetString16(test, 2), Eq(u"goodbye"));
- EXPECT_EQ(StringPiece(sLongString), util::GetString(test, 2));
- EXPECT_EQ(util::Utf8ToUtf16(sLongString), util::GetString16(test, 2).to_string());
+ EXPECT_THAT(util::GetString(test, 3), Eq(sLongString));
+ EXPECT_THAT(util::GetString16(test, 3), Eq(util::Utf8ToUtf16(sLongString)));
size_t len;
- EXPECT_TRUE(test.stringAt(3, &len) != nullptr ||
- test.string8At(3, &len) != nullptr);
+ EXPECT_TRUE(test.stringAt(4, &len) != nullptr || test.string8At(4, &len) != nullptr);
- EXPECT_EQ(std::string("style"), util::GetString(test, 4));
- EXPECT_EQ(StringPiece16(u"style"), util::GetString16(test, 4));
+ EXPECT_THAT(util::GetString(test, 0), Eq("style"));
+ EXPECT_THAT(util::GetString16(test, 0), Eq(u"style"));
- const ResStringPool_span* span = test.styleAt(4);
- ASSERT_NE(nullptr, span);
- EXPECT_EQ(std::string("b"), util::GetString(test, span->name.index));
- EXPECT_EQ(StringPiece16(u"b"), util::GetString16(test, span->name.index));
- EXPECT_EQ(0u, span->firstChar);
- EXPECT_EQ(1u, span->lastChar);
+ const ResStringPool_span* span = test.styleAt(0);
+ ASSERT_THAT(span, NotNull());
+ EXPECT_THAT(util::GetString(test, span->name.index), Eq("b"));
+ EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"b"));
+ EXPECT_THAT(span->firstChar, Eq(0u));
+ EXPECT_THAT(span->lastChar, Eq(1u));
span++;
- ASSERT_NE(ResStringPool_span::END, span->name.index);
- EXPECT_EQ(std::string("i"), util::GetString(test, span->name.index));
- EXPECT_EQ(StringPiece16(u"i"), util::GetString16(test, span->name.index));
- EXPECT_EQ(2u, span->firstChar);
- EXPECT_EQ(3u, span->lastChar);
+ ASSERT_THAT(span->name.index, Ne(ResStringPool_span::END));
+ EXPECT_THAT(util::GetString(test, span->name.index), Eq("i"));
+ EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"i"));
+ EXPECT_THAT(span->firstChar, Eq(2u));
+ EXPECT_THAT(span->lastChar, Eq(3u));
span++;
- EXPECT_EQ(ResStringPool_span::END, span->name.index);
+ EXPECT_THAT(span->name.index, Eq(ResStringPool_span::END));
}
}
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 8741b7b..e1c45d6 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -179,6 +179,13 @@
xml::Attribute{"", "configForSplit", app_info.split_name.value()});
}
+ // Splits may contain more configurations than originally desired (fallback densities, etc.).
+ // This makes programmatic discovery of split targetting difficult. Encode the original
+ // split constraints intended for this split.
+ std::stringstream target_config_str;
+ target_config_str << util::Joiner(constraints.configs, ",");
+ manifest_el->attributes.push_back(xml::Attribute{"", "targetConfig", target_config_str.str()});
+
std::unique_ptr<xml::Element> application_el = util::make_unique<xml::Element>();
application_el->name = "application";
application_el->attributes.push_back(
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index a031ea4..871ed4f 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -120,7 +120,7 @@
// All Span indices are UTF-16 based, according to the resources.arsc format expected by the
// runtime. So we will do all our processing in UTF-16, then convert back.
- const std::u16string text16 = util::Utf8ToUtf16(*string->value->str);
+ const std::u16string text16 = util::Utf8ToUtf16(string->value->value);
// Convenient wrapper around the text that allows us to work with StringPieces.
const StringPiece16 text(text16);
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index b08e1da..711558a 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -31,7 +31,7 @@
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
Pseudolocalizer::Method::kNone, &pool);
- EXPECT_EQ(original_style.str, *new_string->value->str);
+ EXPECT_EQ(original_style.str, new_string->value->value);
ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
EXPECT_EQ(std::string("i"), *new_string->value->spans[0].name);
@@ -52,7 +52,7 @@
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
Pseudolocalizer::Method::kAccent, &pool);
- EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *new_string->value->str);
+ EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), new_string->value->value);
ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
@@ -79,7 +79,7 @@
Pseudolocalizer::Method::kAccent, &pool);
ASSERT_NE(nullptr, new_string);
ASSERT_EQ(2u, new_string->value->spans.size());
- EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
+ EXPECT_EQ(std::string("[ɓöļð one]"), new_string->value->value);
EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
@@ -101,7 +101,7 @@
Pseudolocalizer::Method::kAccent, &pool);
ASSERT_NE(nullptr, new_string);
ASSERT_EQ(2u, new_string->value->spans.size());
- EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
+ EXPECT_EQ(std::string("[ɓöļð one]"), new_string->value->value);
EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
@@ -126,7 +126,7 @@
ASSERT_EQ(4u, new_string->value->spans.size());
EXPECT_EQ(std::string(
"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļļ. one two three four five six]"),
- *new_string->value->str);
+ new_string->value->value);
EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš").size(), new_string->value->spans[0].first_char);
@@ -165,7 +165,7 @@
ASSERT_NE(nullptr, new_string);
ASSERT_EQ(2u, new_string->value->spans.size());
EXPECT_EQ(std::string("[Ţĥîš šĥöûļð NOT ɓé þšéûðöļöçåļîžéð. one two three four]"),
- *new_string->value->str);
+ new_string->value->value);
EXPECT_EQ(std::string("em"), *new_string->value->spans[0].name);
EXPECT_EQ(std::u16string(u"[Ţĥîš").size(), new_string->value->spans[0].first_char);
@@ -265,7 +265,7 @@
ASSERT_NE(nullptr, new_styled_string);
// "world" should be untranslated.
- EXPECT_NE(std::string::npos, new_styled_string->value->str->find("world"));
+ EXPECT_NE(std::string::npos, new_styled_string->value->value.find("world"));
String* new_string = test::GetValueForConfig<String>(table.get(), "android:string/bar",
test::ParseConfigOrDie("en-rXA"));
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index f4d0226..e5993a6 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -557,19 +557,15 @@
} // namespace
bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
- // We must do this before writing the resources, since the string pool IDs may
- // change.
- table->string_pool.Sort(
- [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
- int diff = a.context.priority - b.context.priority;
- if (diff < 0) return true;
- if (diff > 0) return false;
- diff = a.context.config.compare(b.context.config);
- if (diff < 0) return true;
- if (diff > 0) return false;
- return a.value < b.value;
- });
+ // We must do this before writing the resources, since the string pool IDs may change.
table->string_pool.Prune();
+ table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
+ int diff = util::compare(a.priority, b.priority);
+ if (diff == 0) {
+ diff = a.config.compare(b.config);
+ }
+ return diff;
+ });
// Write the ResTable header.
ChunkWriter table_writer(buffer_);
diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp
index bfebedef..331ef78 100644
--- a/tools/aapt2/flatten/XmlFlattener.cpp
+++ b/tools/aapt2/flatten/XmlFlattener.cpp
@@ -180,8 +180,7 @@
flatNode->lineNumber = util::HostToDevice32(node->line_number);
flatNode->comment.index = util::HostToDevice32(-1);
- ResXMLTree_namespaceExt* flat_ns =
- writer.NextBlock<ResXMLTree_namespaceExt>();
+ ResXMLTree_namespaceExt* flat_ns = writer.NextBlock<ResXMLTree_namespaceExt>();
AddString(node->namespace_prefix, kLowPriority, &flat_ns->prefix);
AddString(node->namespace_uri, kLowPriority, &flat_ns->uri);
@@ -289,8 +288,7 @@
BigBuffer* buffer_;
XmlFlattenerOptions options_;
- // Scratch vector to filter attributes. We avoid allocations
- // making this a member.
+ // Scratch vector to filter attributes. We avoid allocations making this a member.
std::vector<xml::Attribute*> filtered_attrs_;
};
@@ -307,10 +305,9 @@
}
// Sort the string pool so that attribute resource IDs show up first.
- visitor.pool.Sort(
- [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
- return a.context.priority < b.context.priority;
- });
+ visitor.pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
+ return util::compare(a.priority, b.priority);
+ });
// Now we flatten the string pool references into the correct places.
for (const auto& ref_entry : visitor.string_refs) {
@@ -328,15 +325,13 @@
// Write the array of resource IDs, indexed by StringPool order.
ChunkWriter res_id_map_writer(buffer_);
res_id_map_writer.StartChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE);
- for (const auto& str : visitor.pool) {
- ResourceId id = {str->context.priority};
- if (id.id == kLowPriority || !id.is_valid()) {
- // When we see the first non-resource ID,
- // we're done.
+ for (const auto& str : visitor.pool.strings()) {
+ ResourceId id(str->context.priority);
+ if (str->context.priority == kLowPriority || !id.is_valid()) {
+ // When we see the first non-resource ID, we're done.
break;
}
-
- *res_id_map_writer.NextBlock<uint32_t>() = id.id;
+ *res_id_map_writer.NextBlock<uint32_t>() = util::HostToDevice32(id.id);
}
res_id_map_writer.Finish();
}
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index a0ef00b..1f83fa0 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -18,12 +18,29 @@
#include <algorithm>
+#include "text/Unicode.h"
+#include "text/Utf8Iterator.h"
#include "util/Util.h"
-using android::StringPiece;
+using ::aapt::text::Utf8Iterator;
+using ::android::StringPiece;
namespace aapt {
+StringPiece AnnotationProcessor::ExtractFirstSentence(const StringPiece& comment) {
+ Utf8Iterator iter(comment);
+ while (iter.HasNext()) {
+ const char32_t codepoint = iter.Next();
+ if (codepoint == U'.') {
+ const size_t current_position = iter.Position();
+ if (!iter.HasNext() || text::IsWhitespace(iter.Next())) {
+ return comment.substr(0, current_position);
+ }
+ }
+ }
+ return comment;
+}
+
void AnnotationProcessor::AppendCommentLine(std::string& comment) {
static const std::string sDeprecated = "@deprecated";
static const std::string sSystemApi = "@SystemApi";
diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h
index 99cd44f..a06eda0 100644
--- a/tools/aapt2/java/AnnotationProcessor.h
+++ b/tools/aapt2/java/AnnotationProcessor.h
@@ -53,6 +53,8 @@
*/
class AnnotationProcessor {
public:
+ static android::StringPiece ExtractFirstSentence(const android::StringPiece& comment);
+
/**
* Adds more comments. Since resources can have various values with different
* configurations,
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index 3e43c42..9ccac88 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -18,6 +18,10 @@
#include "test/Test.h"
+using ::testing::Eq;
+using ::testing::HasSubstr;
+using ::testing::Not;
+
namespace aapt {
TEST(AnnotationProcessorTest, EmitsDeprecated) {
@@ -33,7 +37,7 @@
processor.WriteToStream(&result, "");
std::string annotations = result.str();
- EXPECT_NE(std::string::npos, annotations.find("@Deprecated"));
+ EXPECT_THAT(annotations, HasSubstr("@Deprecated"));
}
TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) {
@@ -44,10 +48,20 @@
processor.WriteToStream(&result, "");
std::string annotations = result.str();
- EXPECT_NE(std::string::npos,
- annotations.find("@android.annotation.SystemApi"));
- EXPECT_EQ(std::string::npos, annotations.find("@SystemApi"));
- EXPECT_NE(std::string::npos, annotations.find("This is a system API"));
+ EXPECT_THAT(annotations, HasSubstr("@android.annotation.SystemApi"));
+ EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi")));
+ EXPECT_THAT(annotations, HasSubstr("This is a system API"));
+}
+
+TEST(AnnotationProcessor, ExtractsFirstSentence) {
+ EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence("This is the only sentence"),
+ Eq("This is the only sentence"));
+ EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence(
+ "This is the\n first sentence. This is the rest of the paragraph."),
+ Eq("This is the\n first sentence."));
+ EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence(
+ "This is the first sentence with a {@link android.R.styleable.Theme}."),
+ Eq("This is the first sentence with a {@link android.R.styleable.Theme}."));
}
} // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 2a23aa9..44fa0f1 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -299,24 +299,16 @@
}
const ResourceName& attr_name = entry.attr_ref->name.value();
- styleable_comment << "<tr><td>";
- styleable_comment << "<code>{@link #" << entry.field_name << " "
- << (!attr_name.package.empty()
- ? attr_name.package
- : context_->GetCompilationPackage())
- << ":" << attr_name.entry << "}</code>";
- styleable_comment << "</td>";
-
- styleable_comment << "<td>";
+ styleable_comment << "<tr><td><code>{@link #" << entry.field_name << " "
+ << (!attr_name.package.empty() ? attr_name.package
+ : context_->GetCompilationPackage())
+ << ":" << attr_name.entry << "}</code></td>";
// Only use the comment up until the first '.'. This is to stay compatible with
// the way old AAPT did it (presumably to keep it short and to avoid including
// annotations like @hide which would affect this Styleable).
- auto iter = std::find(attr_comment_line.begin(), attr_comment_line.end(), '.');
- if (iter != attr_comment_line.end()) {
- attr_comment_line = attr_comment_line.substr(0, (iter - attr_comment_line.begin()) + 1);
- }
- styleable_comment << attr_comment_line << "</td></tr>\n";
+ styleable_comment << "<td>" << AnnotationProcessor::ExtractFirstSentence(attr_comment_line)
+ << "</td></tr>\n";
}
styleable_comment << "</table>\n";
diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp
index 38bf4e3..6b21364 100644
--- a/tools/aapt2/proto/ProtoHelpers.cpp
+++ b/tools/aapt2/proto/ProtoHelpers.cpp
@@ -18,8 +18,7 @@
namespace aapt {
-void SerializeStringPoolToPb(const StringPool& pool,
- pb::StringPool* out_pb_pool) {
+void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool) {
BigBuffer buffer(1024);
StringPool::FlattenUtf8(&buffer, pool);
@@ -28,14 +27,12 @@
size_t offset = 0;
for (const BigBuffer::Block& block : buffer) {
- data->insert(data->begin() + offset, block.buffer.get(),
- block.buffer.get() + block.size);
+ data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
offset += block.size;
}
}
-void SerializeSourceToPb(const Source& source, StringPool* src_pool,
- pb::Source* out_pb_source) {
+void SerializeSourceToPb(const Source& source, StringPool* src_pool, pb::Source* out_pb_source) {
StringPool::Ref ref = src_pool->MakeRef(source.path);
out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index()));
if (source.line) {
@@ -43,8 +40,7 @@
}
}
-void DeserializeSourceFromPb(const pb::Source& pb_source,
- const android::ResStringPool& src_pool,
+void DeserializeSourceFromPb(const pb::Source& pb_source, const android::ResStringPool& src_pool,
Source* out_source) {
if (pb_source.has_path_idx()) {
out_source->path = util::GetString(src_pool, pb_source.path_idx());
@@ -80,8 +76,7 @@
return SymbolState::kUndefined;
}
-void SerializeConfig(const ConfigDescription& config,
- pb::ConfigDescription* out_pb_config) {
+void SerializeConfig(const ConfigDescription& config, pb::ConfigDescription* out_pb_config) {
android::ResTable_config flat_config = config;
flat_config.size = sizeof(flat_config);
flat_config.swapHtoD();
@@ -99,8 +94,7 @@
return false;
}
- config = reinterpret_cast<const android::ResTable_config*>(
- pb_config.data().data());
+ config = reinterpret_cast<const android::ResTable_config*>(pb_config.data().data());
out_config->copyFromDtoH(*config);
return true;
}
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index 4b56192..37d5ed0 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -195,8 +195,7 @@
spans++;
}
return util::make_unique<StyledString>(pool->MakeRef(
- style_str,
- StringPool::Context(StringPool::Context::kStylePriority, config)));
+ style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
}
return util::make_unique<String>(
pool->MakeRef(str, StringPool::Context(config)));
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index d87d64e..730442c 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -87,7 +87,9 @@
pb_prim->set_data(val.data);
}
- void VisitItem(Item* item) override { LOG(FATAL) << "unimplemented item"; }
+ void VisitItem(Item* item) override {
+ LOG(FATAL) << "unimplemented item";
+ }
void Visit(Attribute* attr) override {
pb::Attribute* pb_attr = pb_compound_value()->mutable_attr();
@@ -207,19 +209,15 @@
} // namespace
std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table) {
- // We must do this before writing the resources, since the string pool IDs may
- // change.
- table->string_pool.Sort(
- [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
- int diff = a.context.priority - b.context.priority;
- if (diff < 0) return true;
- if (diff > 0) return false;
- diff = a.context.config.compare(b.context.config);
- if (diff < 0) return true;
- if (diff > 0) return false;
- return a.value < b.value;
- });
+ // We must do this before writing the resources, since the string pool IDs may change.
table->string_pool.Prune();
+ table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
+ int diff = util::compare(a.priority, b.priority);
+ if (diff == 0) {
+ diff = a.config.compare(b.config);
+ }
+ return diff;
+ });
auto pb_table = util::make_unique<pb::ResourceTable>();
SerializeStringPoolToPb(table->string_pool, pb_table->mutable_string_pool());
diff --git a/tools/aapt2/text/Unicode.cpp b/tools/aapt2/text/Unicode.cpp
index 38ec9c4..75eeb46 100644
--- a/tools/aapt2/text/Unicode.cpp
+++ b/tools/aapt2/text/Unicode.cpp
@@ -66,6 +66,17 @@
return FindCharacterProperties(codepoint) & CharacterProperties::kXidContinue;
}
+// Hardcode the White_Space characters since they are few and the external/icu project doesn't
+// list them as data files to parse.
+// Sourced from http://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
+bool IsWhitespace(char32_t codepoint) {
+ return (codepoint >= 0x0009 && codepoint <= 0x000d) || (codepoint == 0x0020) ||
+ (codepoint == 0x0085) || (codepoint == 0x00a0) || (codepoint == 0x1680) ||
+ (codepoint >= 0x2000 && codepoint <= 0x200a) || (codepoint == 0x2028) ||
+ (codepoint == 0x2029) || (codepoint == 0x202f) || (codepoint == 0x205f) ||
+ (codepoint == 0x3000);
+}
+
bool IsJavaIdentifier(const StringPiece& str) {
Utf8Iterator iter(str);
diff --git a/tools/aapt2/text/Unicode.h b/tools/aapt2/text/Unicode.h
index 2707187..546714e 100644
--- a/tools/aapt2/text/Unicode.h
+++ b/tools/aapt2/text/Unicode.h
@@ -40,6 +40,10 @@
// characters in the ID_Continue set.
bool IsXidContinue(char32_t codepoint);
+// Returns true if the Unicode codepoint has the White_Space property.
+// http://unicode.org/reports/tr44/#White_Space
+bool IsWhitespace(char32_t codepoint);
+
// Returns true if the UTF8 string can be used as a Java identifier.
// NOTE: This does not check against the set of reserved Java keywords.
bool IsJavaIdentifier(const android::StringPiece& str);
diff --git a/tools/aapt2/text/Utf8Iterator.cpp b/tools/aapt2/text/Utf8Iterator.cpp
index 0d43353..20b9073 100644
--- a/tools/aapt2/text/Utf8Iterator.cpp
+++ b/tools/aapt2/text/Utf8Iterator.cpp
@@ -25,18 +25,17 @@
namespace text {
Utf8Iterator::Utf8Iterator(const StringPiece& str)
- : str_(str), next_pos_(0), current_codepoint_(0) {
+ : str_(str), current_pos_(0), next_pos_(0), current_codepoint_(0) {
DoNext();
}
void Utf8Iterator::DoNext() {
- size_t next_pos = 0u;
- int32_t result = utf32_from_utf8_at(str_.data(), str_.size(), next_pos_, &next_pos);
+ current_pos_ = next_pos_;
+ int32_t result = utf32_from_utf8_at(str_.data(), str_.size(), current_pos_, &next_pos_);
if (result == -1) {
current_codepoint_ = 0u;
} else {
current_codepoint_ = static_cast<char32_t>(result);
- next_pos_ = next_pos;
}
}
@@ -44,6 +43,10 @@
return current_codepoint_ != 0;
}
+size_t Utf8Iterator::Position() const {
+ return current_pos_;
+}
+
void Utf8Iterator::Skip(int amount) {
while (amount > 0 && HasNext()) {
Next();
diff --git a/tools/aapt2/text/Utf8Iterator.h b/tools/aapt2/text/Utf8Iterator.h
index 6923957..9318401 100644
--- a/tools/aapt2/text/Utf8Iterator.h
+++ b/tools/aapt2/text/Utf8Iterator.h
@@ -29,6 +29,10 @@
bool HasNext() const;
+ // Returns the current position of the iterator in bytes of the source UTF8 string.
+ // This position is the start of the codepoint returned by the next call to Next().
+ size_t Position() const;
+
void Skip(int amount);
char32_t Next();
@@ -39,6 +43,7 @@
void DoNext();
android::StringPiece str_;
+ size_t current_pos_;
size_t next_pos_;
char32_t current_codepoint_;
};
diff --git a/tools/aapt2/text/Utf8Iterator_test.cpp b/tools/aapt2/text/Utf8Iterator_test.cpp
index f3111c0..8c3e774 100644
--- a/tools/aapt2/text/Utf8Iterator_test.cpp
+++ b/tools/aapt2/text/Utf8Iterator_test.cpp
@@ -18,6 +18,7 @@
#include "test/Test.h"
+using ::android::StringPiece;
using ::testing::Eq;
namespace aapt {
@@ -63,5 +64,32 @@
EXPECT_FALSE(iter.HasNext());
}
+TEST(Utf8IteratorTest, PositionPointsToTheCorrectPlace) {
+ const StringPiece expected("Mm🍩");
+ Utf8Iterator iter(expected);
+
+ // Before any character, the position should be 0.
+ EXPECT_THAT(iter.Position(), Eq(0u));
+
+ // The 'M' character, one byte.
+ ASSERT_TRUE(iter.HasNext());
+ iter.Next();
+ EXPECT_THAT(iter.Position(), Eq(1u));
+
+ // The 'm' character, one byte.
+ ASSERT_TRUE(iter.HasNext());
+ iter.Next();
+ EXPECT_THAT(iter.Position(), Eq(2u));
+
+ // The doughnut character, 4 bytes.
+ ASSERT_TRUE(iter.HasNext());
+ iter.Next();
+ EXPECT_THAT(iter.Position(), Eq(6u));
+
+ // There should be nothing left.
+ EXPECT_FALSE(iter.HasNext());
+ EXPECT_THAT(iter.Position(), Eq(expected.size()));
+}
+
} // namespace text
} // namespace aapt
diff --git a/tools/aapt2/tools/extract_unicode_properties.py b/tools/aapt2/tools/extract_unicode_properties.py
index d7e0479..7577ec8 100644
--- a/tools/aapt2/tools/extract_unicode_properties.py
+++ b/tools/aapt2/tools/extract_unicode_properties.py
@@ -35,9 +35,8 @@
return "{}0x{:04x}, 0x{:04x}, {}{}".format(
"{", self.first_char, self.last_char, ' | '.join(types), "}")
-def extract_unicode_properties(f, props):
- prog = re.compile(r"^(?P<first>\w{4})(..(?P<last>\w{4}))?\W+;\W+(?P<prop>\w+)\n$")
- chars = {}
+def extract_unicode_properties(f, props, chars_out):
+ prog = re.compile(r"^(?P<first>\w{4})(..(?P<last>\w{4}))?\W+;\W+(?P<prop>\w+)")
for line in f:
result = prog.match(line)
if result:
@@ -49,10 +48,12 @@
last_char = (int(last_char_str, 16) if last_char_str else start_char) + 1
prop_type = props[prop_type_str]
for char in range(start_char, last_char):
- if char not in chars:
- chars[char] = CharacterProperty(char, char, 0)
- chars[char].prop_type |= prop_type
+ if char not in chars_out:
+ chars_out[char] = CharacterProperty(char, char, 0)
+ chars_out[char].prop_type |= prop_type
+ return chars_out
+def flatten_unicode_properties(chars):
result = []
for char_prop in sorted(chars.values(), key=CharacterProperty.key):
if len(result) == 0:
@@ -82,17 +83,20 @@
"""
if __name__ == "__main__":
- if len(sys.argv) != 2:
+ if len(sys.argv) < 2:
print("must specify path to icu DerivedCoreProperties file (e.g:" \
"external/icu/icu4c/source/data/unidata/DerivedCoreProperties.txt)")
sys.exit(1)
- with open(sys.argv[1]) as f:
- props = {"XID_Start": 1, "XID_Continue": 2}
- char_props = extract_unicode_properties(f, props)
- print("{}\nconst static std::array<CharacterProperties, {}> sCharacterProperties = {}"
- .format(license, len(char_props), "{{"))
- for prop in char_props:
- print(" {},".format(prop))
- print("}};")
+ props = {"XID_Start": 1, "XID_Continue": 2}
+ char_props = {}
+ for file_path in sys.argv[1:]:
+ with open(file_path) as f:
+ extract_unicode_properties(f, props, char_props)
+ result = flatten_unicode_properties(char_props)
+ print("{}\nconst static std::array<CharacterProperties, {}> sCharacterProperties = {}"
+ .format(license, len(result), "{{"))
+ for prop in result:
+ print(" {},".format(prop))
+ print("}};")
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index f311670..728d1f4 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -38,20 +38,17 @@
using namespace android;
-using android::base::StringPrintf;
+using ::android::base::StringPrintf;
namespace {
-/*
- * Visitor that converts a reference's resource ID to a resource name,
- * given a mapping from resource ID to resource name.
- */
+// Visitor that converts a reference's resource ID to a resource name, given a mapping from
+// resource ID to resource name.
class ReferenceIdToNameVisitor : public ValueVisitor {
public:
using ValueVisitor::Visit;
- explicit ReferenceIdToNameVisitor(
- const std::map<ResourceId, ResourceName>* mapping)
+ explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceName>* mapping)
: mapping_(mapping) {
CHECK(mapping_ != nullptr);
}
@@ -99,7 +96,7 @@
if (parser.chunk()->type != android::RES_TABLE_TYPE) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
<< StringPrintf("unknown chunk of type 0x%02x",
- (int)parser.chunk()->type));
+ static_cast<int>(parser.chunk()->type)));
return false;
}
@@ -115,7 +112,7 @@
context_->GetDiagnostics()->Warn(
DiagMessage(source_) << StringPrintf(
"unexpected chunk of type 0x%02x trailing RES_TABLE_TYPE",
- (int)parser.chunk()->type));
+ static_cast<int>(parser.chunk()->type)));
}
}
return true;
@@ -165,9 +162,8 @@
default:
context_->GetDiagnostics()->Warn(
- DiagMessage(source_)
- << "unexpected chunk type "
- << (int)util::DeviceToHost16(parser.chunk()->type));
+ DiagMessage(source_) << "unexpected chunk type "
+ << static_cast<int>(util::DeviceToHost16(parser.chunk()->type)));
break;
}
}
@@ -245,8 +241,7 @@
return false;
}
} else {
- context_->GetDiagnostics()->Warn(DiagMessage(source_)
- << "unexpected string pool");
+ context_->GetDiagnostics()->Warn(DiagMessage(source_) << "unexpected string pool");
}
break;
@@ -270,9 +265,8 @@
default:
context_->GetDiagnostics()->Warn(
- DiagMessage(source_)
- << "unexpected chunk type "
- << (int)util::DeviceToHost16(parser.chunk()->type));
+ DiagMessage(source_) << "unexpected chunk type "
+ << static_cast<int>(util::DeviceToHost16(parser.chunk()->type)));
break;
}
}
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index b9ada77..ad3989e 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -70,12 +70,6 @@
android::StringPiece TrimWhitespace(const android::StringPiece& str);
/**
- * UTF-16 isspace(). It basically checks for lower range characters that are
- * whitespace.
- */
-inline bool isspace16(char16_t c) { return c < 0x0080 && isspace(c); }
-
-/**
* Returns an iterator to the first character that is not alpha-numeric and that
* is not in the allowedChars set.
*/
@@ -104,6 +98,16 @@
Maybe<std::string> GetFullyQualifiedClassName(const android::StringPiece& package,
const android::StringPiece& class_name);
+template <typename T>
+typename std::enable_if<std::is_arithmetic<T>::value, int>::type compare(const T& a, const T& b) {
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ }
+ return 0;
+}
+
/**
* Makes a std::unique_ptr<> with the template parameter inferred by the compiler.
* This will be present in C++14 and can be removed then.
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index a7fbc2e..91ca514 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -50,6 +50,7 @@
int testPassCount;
int testFailCount;
+ int unknownFailureCount; // unknown failure == "Process crashed", etc.
bool actionsWithNoTests;
Target(bool b, bool i, bool t, const string& p);
@@ -63,6 +64,7 @@
testActionCount(0),
testPassCount(0),
testFailCount(0),
+ unknownFailureCount(0),
actionsWithNoTests(false)
{
}
@@ -188,8 +190,13 @@
*/
void SetCurrentAction(TestAction* action);
+ bool IsSuccess();
+
+ string GetErrorMessage();
+
private:
TestAction* m_currentAction;
+ SessionStatus m_sessionStatus;
};
void
@@ -241,8 +248,10 @@
}
line << ": " << m_currentAction->target->name << ':' << className << "\\#" << testName;
print_one_line("%s", line.str().c_str());
- } else if (resultCode == -2) {
+ } else if ((resultCode == -1) || (resultCode == -2)) {
// test failed
+ // Note -2 means an assertion failure, and -1 means other exceptions. We just treat them
+ // all as "failures".
m_currentAction->failCount++;
m_currentAction->target->testFailCount++;
printf("%s\n%sFailed: %s:%s\\#%s%s\n", g_escapeClearLine, g_escapeRedBold,
@@ -257,9 +266,13 @@
}
void
-TestResults::OnSessionStatus(SessionStatus& /*status*/)
+TestResults::OnSessionStatus(SessionStatus& status)
{
//status.PrintDebugString();
+ m_sessionStatus = status;
+ if (m_currentAction && !IsSuccess()) {
+ m_currentAction->target->unknownFailureCount++;
+ }
}
void
@@ -268,6 +281,24 @@
m_currentAction = action;
}
+bool
+TestResults::IsSuccess()
+{
+ return m_sessionStatus.result_code() == -1; // Activity.RESULT_OK.
+}
+
+string
+TestResults::GetErrorMessage()
+{
+ bool found;
+ string shortMsg = get_bundle_string(m_sessionStatus.results(), &found, "shortMsg", NULL);
+ if (!found) {
+ return IsSuccess() ? "" : "Unknown failure";
+ }
+ return shortMsg;
+}
+
+
/**
* Prints the usage statement / help text.
*/
@@ -568,7 +599,7 @@
/**
* Run the build, install, and test actions.
*/
-void
+bool
run_phases(vector<Target*> targets, const Options& options)
{
int err = 0;
@@ -837,6 +868,10 @@
printf("%s%d passed%s, %d failed\n", g_escapeGreenBold, action.passCount,
g_escapeEndColor, action.failCount);
}
+ if (!testResults.IsSuccess()) {
+ printf("\n%sTest didn't finish successfully: %s%s\n", g_escapeRedBold,
+ testResults.GetErrorMessage().c_str(), g_escapeEndColor);
+ }
}
}
@@ -907,6 +942,7 @@
}
// Tests
+ bool hasErrors = false;
if (testActions.size() > 0) {
printf("%sRan tests:%s\n", g_escapeBold, g_escapeEndColor);
size_t maxNameLength = 0;
@@ -924,12 +960,18 @@
Target* target = targets[i];
if (target->testActionCount > 0) {
printf(" %s%s", target->name.c_str(), padding.c_str() + target->name.length());
- if (target->actionsWithNoTests) {
+ if (target->unknownFailureCount > 0) {
+ printf(" %sUnknown failure, see above message.%s\n",
+ g_escapeRedBold, g_escapeEndColor);
+ hasErrors = true;
+ } else if (target->actionsWithNoTests) {
printf(" %s%d passed, %d failed%s\n", g_escapeYellowBold,
target->testPassCount, target->testFailCount, g_escapeEndColor);
+ hasErrors = true;
} else if (target->testFailCount > 0) {
printf(" %d passed, %s%d failed%s\n", target->testPassCount,
g_escapeRedBold, target->testFailCount, g_escapeEndColor);
+ hasErrors = true;
} else {
printf(" %s%d passed%s, %d failed\n", g_escapeGreenBold,
target->testPassCount, g_escapeEndColor, target->testFailCount);
@@ -944,6 +986,7 @@
}
printf("%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);
+ return !hasErrors;
}
/**
@@ -991,7 +1034,7 @@
exit(0);
} else {
// Normal run
- run_phases(options.targets, options);
+ exit(run_phases(options.targets, options) ? 0 : 1);
}
return 0;
diff --git a/wifi/java/android/net/wifi/IRttManager.aidl b/wifi/java/android/net/wifi/IRttManager.aidl
index 90f66c4..3831809 100644
--- a/wifi/java/android/net/wifi/IRttManager.aidl
+++ b/wifi/java/android/net/wifi/IRttManager.aidl
@@ -23,6 +23,6 @@
*/
interface IRttManager
{
- Messenger getMessenger();
+ Messenger getMessenger(in IBinder binder, out int[] key);
RttManager.RttCapabilities getRttCapabilities();
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 7972d06..a3a1054 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -94,7 +94,7 @@
void reassociate();
- WifiInfo getConnectionInfo();
+ WifiInfo getConnectionInfo(String callingPackage);
boolean setWifiEnabled(String packageName, boolean enable);
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index a4b3bf2a..ac5df05 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -6,6 +6,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -1187,6 +1188,8 @@
CMD_OP_ENALBE_RESPONDER_SUCCEEDED = BASE + 7;
public static final int
CMD_OP_ENALBE_RESPONDER_FAILED = BASE + 8;
+ /** @hide */
+ public static final int CMD_OP_REG_BINDER = BASE + 9;
private static final int INVALID_KEY = 0;
@@ -1215,9 +1218,10 @@
mContext = context;
mService = service;
Messenger messenger = null;
+ int[] key = new int[1];
try {
Log.d(TAG, "Get the messenger from " + mService);
- messenger = mService.getMessenger();
+ messenger = mService.getMessenger(new Binder(), key);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1233,6 +1237,7 @@
// We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
// synchronously, which causes RttService to receive the wrong replyTo value.
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+ mAsyncChannel.sendMessage(CMD_OP_REG_BINDER, key[0]);
}
private void validateChannel() {
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index afee290..a552e62 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -431,6 +431,28 @@
*/
public AnqpInformationElement[] anqpElements;
+ /**
+ * Flag indicating if this AP is a carrier AP. The determination is based
+ * on the AP's SSID and if AP is using EAP security.
+ *
+ * @hide
+ */
+ public boolean isCarrierAp;
+
+ /**
+ * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP.
+ *
+ * @hide
+ */
+ public int carrierApEapType;
+
+ /**
+ * The name of the carrier that's associated with this AP if it is a carrier AP.
+ *
+ * @hide
+ */
+ public String carrierName;
+
/** {@hide} */
public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
byte[] osuProviders, String caps, int level, int frequency, long tsf) {
@@ -455,6 +477,9 @@
this.centerFreq0 = UNSPECIFIED;
this.centerFreq1 = UNSPECIFIED;
this.flags = 0;
+ this.isCarrierAp = false;
+ this.carrierApEapType = UNSPECIFIED;
+ this.carrierName = null;
}
/** {@hide} */
@@ -473,6 +498,9 @@
this.centerFreq0 = UNSPECIFIED;
this.centerFreq1 = UNSPECIFIED;
this.flags = 0;
+ this.isCarrierAp = false;
+ this.carrierApEapType = UNSPECIFIED;
+ this.carrierName = null;
}
/** {@hide} */
@@ -498,6 +526,9 @@
} else {
this.flags = 0;
}
+ this.isCarrierAp = false;
+ this.carrierApEapType = UNSPECIFIED;
+ this.carrierName = null;
}
/** {@hide} */
@@ -537,6 +568,9 @@
venueName = source.venueName;
operatorFriendlyName = source.operatorFriendlyName;
flags = source.flags;
+ isCarrierAp = source.isCarrierAp;
+ carrierApEapType = source.carrierApEapType;
+ carrierName = source.carrierName;
}
}
@@ -577,6 +611,9 @@
sb.append(", centerFreq1: ").append(centerFreq1);
sb.append(", 80211mcResponder: ");
sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
+ sb.append(", Carrier AP: ").append(isCarrierAp ? "yes" : "no");
+ sb.append(", Carrier AP EAP Type: ").append(carrierApEapType);
+ sb.append(", Carrier name: ").append(carrierName);
return sb.toString();
}
@@ -646,6 +683,9 @@
} else {
dest.writeInt(0);
}
+ dest.writeInt(isCarrierAp ? 1 : 0);
+ dest.writeInt(carrierApEapType);
+ dest.writeString(carrierName);
}
/** Implement the Parcelable interface {@hide} */
@@ -715,6 +755,9 @@
new AnqpInformationElement(vendorId, elementId, payload);
}
}
+ sr.isCarrierAp = in.readInt() != 0;
+ sr.carrierApEapType = in.readInt();
+ sr.carrierName = in.readString();
return sr;
}
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index f8485ef..a367b23 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -151,8 +151,9 @@
/**
* This factor is used to adjust the rate output under the new algorithm
* such that the result is comparable to the previous algorithm.
+ * This actually converts from unit 'packets per second' to 'packets per 5 seconds'.
*/
- private static final long OUTPUT_SCALE_FACTOR = 5000;
+ private static final long OUTPUT_SCALE_FACTOR = 5;
private long mLastPacketCountUpdateTimeStamp;
/**
@@ -198,16 +199,16 @@
double currentSampleWeight = 1.0 - lastSampleWeight;
txBadRate = txBadRate * lastSampleWeight
- + (txbad - txBad) * OUTPUT_SCALE_FACTOR / timeDelta
+ + (txbad - txBad) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
* currentSampleWeight;
txSuccessRate = txSuccessRate * lastSampleWeight
- + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+ + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
* currentSampleWeight;
rxSuccessRate = rxSuccessRate * lastSampleWeight
- + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+ + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
* currentSampleWeight;
txRetriesRate = txRetriesRate * lastSampleWeight
- + (txretries - txRetries) * OUTPUT_SCALE_FACTOR / timeDelta
+ + (txretries - txRetries) * OUTPUT_SCALE_FACTOR * 1000/ timeDelta
* currentSampleWeight;
} else {
txBadRate = 0;
@@ -345,7 +346,8 @@
* Returns the service set identifier (SSID) of the current 802.11 network.
* If the SSID can be decoded as UTF-8, it will be returned surrounded by double
* quotation marks. Otherwise, it is returned as a string of hex digits. The
- * SSID may be <unknown ssid> if there is no network currently connected.
+ * SSID may be <unknown ssid> if there is no network currently connected,
+ * or if the caller has insufficient permissions to access the SSID.
* @return the SSID
*/
public String getSSID() {
@@ -447,6 +449,22 @@
}
/**
+ * @hide
+ * This returns txSuccessRate in packets per second.
+ */
+ public double getTxSuccessRatePps() {
+ return txSuccessRate / OUTPUT_SCALE_FACTOR;
+ }
+
+ /**
+ * @hide
+ * This returns rxSuccessRate in packets per second.
+ */
+ public double getRxSuccessRatePps() {
+ return rxSuccessRate / OUTPUT_SCALE_FACTOR;
+ }
+
+ /**
* Record the MAC address of the WLAN interface
* @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
* @hide
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 598360c..bc37810 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1633,11 +1633,17 @@
/**
* Return dynamic information about the current Wi-Fi connection, if any is active.
+ * <p>
+ * In the connected state, access to the SSID and BSSID requires
+ * the same permissions as {@link #getScanResults}. If such access is not allowed,
+ * {@link WifiInfo#getSSID} will return {@code "<unknown ssid>"} and
+ * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
+ *
* @return the Wi-Fi information, contained in {@link WifiInfo}.
*/
public WifiInfo getConnectionInfo() {
try {
- return mService.getConnectionInfo();
+ return mService.getConnectionInfo(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2330,7 +2336,7 @@
/** WPS start succeeded */
public abstract void onStarted(String pin);
- /** WPS operation completed succesfully */
+ /** WPS operation completed successfully */
public abstract void onSucceeded();
/**
@@ -3213,7 +3219,7 @@
* Normally the Wifi stack filters out packets not explicitly
* addressed to this device. Acquring a MulticastLock will
* cause the stack to receive packets addressed to multicast
- * addresses. Processing these extra packets can cause a noticable
+ * addresses. Processing these extra packets can cause a noticeable
* battery drain and should be disabled when not needed.
*/
public class MulticastLock {