Merge "Allow an icon to carry a tint with it, wherever it goes." into mnc-dev
diff --git a/Android.mk b/Android.mk
index e96a932..a02b326 100644
--- a/Android.mk
+++ b/Android.mk
@@ -142,6 +142,7 @@
core/java/android/content/pm/IPackageManager.aidl \
core/java/android/content/pm/IPackageMoveObserver.aidl \
core/java/android/content/pm/IPackageStatsObserver.aidl \
+ core/java/android/content/pm/IPackagesProvider.aidl \
core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
core/java/android/database/IContentObserver.aidl \
core/java/android/hardware/ICameraService.aidl \
diff --git a/api/current.txt b/api/current.txt
index ed05d99..aa07a97 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -105,12 +105,9 @@
field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
- field public static final deprecated java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
- field public static final deprecated java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
- field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";
field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL";
field public static final java.lang.String REBOOT = "android.permission.REBOOT";
field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
@@ -152,12 +149,9 @@
field public static final java.lang.String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS";
field public static final java.lang.String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
- field public static final deprecated java.lang.String WRITE_PROFILE = "android.permission.WRITE_PROFILE";
field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
- field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
- field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";
field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL";
}
@@ -172,9 +166,7 @@
field public static final java.lang.String PHONE = "android.permission-group.PHONE";
field public static final java.lang.String SENSORS = "android.permission-group.SENSORS";
field public static final java.lang.String SMS = "android.permission-group.SMS";
- field public static final java.lang.String SOCIAL_INFO = "android.permission-group.SOCIAL_INFO";
field public static final java.lang.String STORAGE = "android.permission-group.STORAGE";
- field public static final java.lang.String USER_DICTIONARY = "android.permission-group.USER_DICTIONARY";
}
public final class R {
@@ -4016,79 +4008,6 @@
field public java.lang.String serviceDetails;
}
- public deprecated class AssistContent {
- ctor public AssistContent();
- method public android.content.ClipData getClipData();
- method public android.os.Bundle getExtras();
- method public java.lang.String getStructuredData();
- method public android.net.Uri getWebUri();
- method public boolean isAppProvidedIntent();
- method public void setClipData(android.content.ClipData);
- method public void setIntent(android.content.Intent);
- method public void setStructuredData(java.lang.String);
- method public void setWebUri(android.net.Uri);
- }
-
- public deprecated class AssistStructure {
- ctor public AssistStructure();
- method public android.content.ComponentName getActivityComponent();
- method public int getWindowNodeCount();
- }
-
- public static class AssistStructure.ViewNode {
- method public android.app.AssistStructure.ViewNode getChildAt(int);
- method public int getChildCount();
- method public java.lang.String getClassName();
- method public java.lang.CharSequence getContentDescription();
- method public android.os.Bundle getExtras();
- method public int getHeight();
- method public java.lang.String getHint();
- method public int getId();
- method public java.lang.String getIdEntry();
- method public java.lang.String getIdPackage();
- method public java.lang.String getIdType();
- method public int getLeft();
- method public int getScrollX();
- method public int getScrollY();
- method public java.lang.CharSequence getText();
- method public int getTextBackgroundColor();
- method public int getTextColor();
- method public int getTextSelectionEnd();
- method public int getTextSelectionStart();
- method public float getTextSize();
- method public int getTextStyle();
- method public int getTop();
- method public int getVisibility();
- method public int getWidth();
- method public boolean isAccessibilityFocused();
- method public boolean isActivated();
- method public boolean isAssistBlocked();
- method public boolean isCheckable();
- method public boolean isChecked();
- method public boolean isClickable();
- method public boolean isContextClickable();
- method public boolean isEnabled();
- method public boolean isFocusable();
- method public boolean isFocused();
- method public boolean isLongClickable();
- method public boolean isSelected();
- field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
- field public static final int TEXT_STYLE_BOLD = 1; // 0x1
- field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
- field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8
- field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
- }
-
- public static class AssistStructure.WindowNode {
- method public int getDisplayId();
- method public int getHeight();
- method public int getLeft();
- method public android.app.AssistStructure.ViewNode getRootViewNode();
- method public java.lang.CharSequence getTitle();
- method public int getTop();
- method public int getWidth();
- }
-
public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {
ctor public DatePickerDialog(android.content.Context, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
ctor public DatePickerDialog(android.content.Context, int, android.app.DatePickerDialog.OnDateSetListener, int, int, int);
@@ -5697,7 +5616,6 @@
field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
- field public static final java.lang.String ACTION_READY_FOR_USER_INITIALIZATION = "android.app.action.READY_FOR_USER_INITIALIZATION";
field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
@@ -5709,7 +5627,6 @@
method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
method public void addUserRestriction(android.content.ComponentName, java.lang.String);
method public void clearCrossProfileIntentFilters(android.content.ComponentName);
- method public void clearDeviceInitializerApp(android.content.ComponentName);
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
@@ -5759,7 +5676,6 @@
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
- method public boolean isDeviceInitializerApp(java.lang.String);
method public boolean isDeviceOwnerApp(java.lang.String);
method public boolean isLockTaskPermitted(java.lang.String);
method public boolean isMasterVolumeMuted(android.content.ComponentName);
@@ -5778,7 +5694,6 @@
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
- method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -5811,7 +5726,6 @@
method public void setSystemUpdatePolicy(android.content.ComponentName, android.app.admin.SystemUpdatePolicy);
method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
- method public boolean setUserEnabled(android.content.ComponentName);
method public void setUserIcon(android.content.ComponentName, android.graphics.Bitmap);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
@@ -5840,12 +5754,6 @@
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
field public static final deprecated java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM";
field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
@@ -5911,22 +5819,87 @@
package android.app.assist {
- public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable {
- ctor public AssistContent(android.os.Parcel);
+ public deprecated class AssistContent implements android.os.Parcelable {
+ ctor public AssistContent();
method public int describeContents();
+ method public android.content.ClipData getClipData();
+ method public android.os.Bundle getExtras();
method public android.content.Intent getIntent();
+ method public java.lang.String getStructuredData();
+ method public android.net.Uri getWebUri();
+ method public boolean isAppProvidedIntent();
+ method public void setClipData(android.content.ClipData);
+ method public void setIntent(android.content.Intent);
+ method public void setStructuredData(java.lang.String);
+ method public void setWebUri(android.net.Uri);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR;
}
- public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable {
+ public class AssistStructure implements android.os.Parcelable {
ctor public AssistStructure();
method public int describeContents();
- method public android.app.AssistStructure.WindowNode getWindowNodeAt(int);
+ method public android.content.ComponentName getActivityComponent();
+ method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int);
+ method public int getWindowNodeCount();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR;
}
+ public static class AssistStructure.ViewNode {
+ method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
+ method public int getChildCount();
+ method public java.lang.String getClassName();
+ method public java.lang.CharSequence getContentDescription();
+ method public android.os.Bundle getExtras();
+ method public int getHeight();
+ method public java.lang.String getHint();
+ method public int getId();
+ method public java.lang.String getIdEntry();
+ method public java.lang.String getIdPackage();
+ method public java.lang.String getIdType();
+ method public int getLeft();
+ method public int getScrollX();
+ method public int getScrollY();
+ method public java.lang.CharSequence getText();
+ method public int getTextBackgroundColor();
+ method public int getTextColor();
+ method public int getTextSelectionEnd();
+ method public int getTextSelectionStart();
+ method public float getTextSize();
+ method public int getTextStyle();
+ method public int getTop();
+ method public int getVisibility();
+ method public int getWidth();
+ method public boolean isAccessibilityFocused();
+ method public boolean isActivated();
+ method public boolean isAssistBlocked();
+ method public boolean isCheckable();
+ method public boolean isChecked();
+ method public boolean isClickable();
+ method public boolean isContextClickable();
+ method public boolean isEnabled();
+ method public boolean isFocusable();
+ method public boolean isFocused();
+ method public boolean isLongClickable();
+ method public boolean isSelected();
+ field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
+ field public static final int TEXT_STYLE_BOLD = 1; // 0x1
+ field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
+ field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8
+ field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
+ }
+
+ public static class AssistStructure.WindowNode {
+ method public int getDisplayId();
+ method public int getHeight();
+ method public int getLeft();
+ method public android.app.assist.AssistStructure.ViewNode getRootViewNode();
+ method public java.lang.CharSequence getTitle();
+ method public int getTop();
+ method public int getWidth();
+ }
+
}
package android.app.backup {
@@ -7222,6 +7195,7 @@
method public android.content.Context getContext();
method public final android.os.IBinder getSyncAdapterBinder();
method public abstract void onPerformSync(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.ContentProviderClient, android.content.SyncResult);
+ method public void onSecurityException(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.SyncResult);
method public void onSyncCanceled();
method public void onSyncCanceled(java.lang.Thread);
field public static final deprecated int LOG_SYNC_DETAILS = 2743; // 0xab7
@@ -12319,7 +12293,6 @@
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void invalidateSelf();
method public boolean isAutoMirrored();
- method public boolean isDither();
method public boolean isFilterBitmap();
method public boolean isStateful();
method public final boolean isVisible();
@@ -12339,7 +12312,7 @@
method public void setChangingConfigurations(int);
method public abstract void setColorFilter(android.graphics.ColorFilter);
method public void setColorFilter(int, android.graphics.PorterDuff.Mode);
- method public void setDither(boolean);
+ method public deprecated void setDither(boolean);
method public void setFilterBitmap(boolean);
method public void setHotspot(float, float);
method public void setHotspotBounds(int, int, int, int);
@@ -13519,7 +13492,6 @@
field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
- field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3; // 0x3
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
field public static final int LENS_FACING_BACK = 1; // 0x1
@@ -13872,6 +13844,7 @@
}
public final class StreamConfigurationMap {
+ method public android.util.Size[] getHighResolutionOutputSizes(int);
method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges();
method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size);
method public android.util.Size[] getHighSpeedVideoSizes();
@@ -18221,7 +18194,6 @@
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
method public void onLost(android.net.Network);
- method public void onPreCheck(android.net.Network);
}
public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -18372,6 +18344,7 @@
method public boolean hasTransport(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
+ field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
field public static final int NET_CAPABILITY_CBS = 5; // 0x5
field public static final int NET_CAPABILITY_DUN = 2; // 0x2
field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
@@ -18386,6 +18359,7 @@
field public static final int NET_CAPABILITY_RCS = 8; // 0x8
field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
+ field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
@@ -19099,6 +19073,8 @@
public class ScanResult implements android.os.Parcelable {
method public int describeContents();
+ method public boolean is80211mcResponder();
+ method public boolean isPasspointNetwork();
method public void writeToParcel(android.os.Parcel, int);
field public java.lang.String BSSID;
field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
@@ -19106,18 +19082,19 @@
field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+ field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L
+ field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L
field public java.lang.String SSID;
field public java.lang.String capabilities;
field public int centerFreq0;
field public int centerFreq1;
field public int channelWidth;
+ field public long flags;
field public int frequency;
- field public boolean is80211McRTTResponder;
field public int level;
- field public java.lang.String operatorFriendlyName;
- field public boolean passpointNetwork;
+ field public java.lang.CharSequence operatorFriendlyName;
field public long timestamp;
- field public java.lang.String venueName;
+ field public java.lang.CharSequence venueName;
}
public final class SupplicantState extends java.lang.Enum implements android.os.Parcelable {
@@ -19160,7 +19137,7 @@
field public java.lang.String preSharedKey;
field public int priority;
field public java.lang.String providerFriendlyName;
- field public java.util.HashSet<java.lang.Long> roamingConsortiumIds;
+ field public java.lang.Long[] roamingConsortiumIds;
field public int status;
field public java.lang.String[] wepKeys;
field public int wepTxKeyIndex;
@@ -19222,7 +19199,7 @@
method public java.lang.String getAnonymousIdentity();
method public java.security.cert.X509Certificate getCaCertificate();
method public java.security.cert.X509Certificate getClientCertificate();
- method public java.lang.String getDomainSubjectMatch();
+ method public java.lang.String getDomainSuffixMatch();
method public int getEapMethod();
method public java.lang.String getIdentity();
method public java.lang.String getPassword();
@@ -23677,6 +23654,7 @@
method public deprecated void setUserRestriction(java.lang.String, boolean);
method public deprecated void setUserRestrictions(android.os.Bundle);
method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
+ field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
@@ -25589,10 +25567,6 @@
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final deprecated class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp";
field public static final java.lang.String DISPLAY_NAME = "display_name";
@@ -25908,10 +25882,6 @@
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
@@ -25982,56 +25952,6 @@
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String PHOTO = "photo";
- }
-
- protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final deprecated java.lang.String PHOTO_URI = "photo_uri";
- field public static final deprecated java.lang.String SORT_INDEX = "sort_index";
- field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final deprecated android.net.Uri CONTENT_LIMIT_URI;
- field public static final deprecated android.net.Uri CONTENT_PHOTO_URI;
- field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final deprecated android.net.Uri CONTENT_URI;
- field public static final deprecated java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract deprecated interface ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name";
- field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final deprecated java.lang.String COMMENTS = "comments";
- field public static final deprecated java.lang.String CONTACT_ID = "contact_id";
- field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final deprecated java.lang.String DATA_SET = "data_set";
- field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final deprecated java.lang.String RES_ICON = "icon";
- field public static final deprecated java.lang.String RES_LABEL = "label";
- field public static final deprecated java.lang.String RES_PACKAGE = "res_package";
- field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1";
- field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2";
- field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3";
- field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4";
- field public static final deprecated java.lang.String TEXT = "text";
- field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
@@ -26595,6 +26515,7 @@
field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+ field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -28615,8 +28536,7 @@
method public final void notifyCarrierNetworkChange(boolean);
method public android.os.IBinder onBind(android.content.Intent);
method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
- field public static final java.lang.String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService";
- field public static final java.lang.String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService";
+ field public static final java.lang.String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
}
public final class MessagePdu implements android.os.Parcelable {
@@ -36645,10 +36565,6 @@
method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float);
}
- public abstract deprecated class ViewAssistStructure extends android.view.ViewStructure {
- ctor public ViewAssistStructure();
- }
-
public class ViewConfiguration {
ctor public deprecated ViewConfiguration();
method public static android.view.ViewConfiguration get(android.content.Context);
@@ -37030,7 +36946,7 @@
ctor public ViewStructure();
method public abstract int addChildCount(int);
method public abstract void asyncCommit();
- method public abstract android.view.ViewAssistStructure asyncNewChild(int);
+ method public abstract android.view.ViewStructure asyncNewChild(int);
method public abstract int getChildCount();
method public abstract android.os.Bundle getExtras();
method public abstract java.lang.CharSequence getHint();
@@ -37038,7 +36954,7 @@
method public abstract int getTextSelectionEnd();
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
- method public abstract android.view.ViewAssistStructure newChild(int);
+ method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setCheckable(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 2e6c685..7fc927b 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -117,6 +117,64 @@
field public static final deprecated java.lang.String URL = "url";
}
+ public static final deprecated class ContactsContract.Contacts.StreamItems {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
+ }
+
+ public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
+ }
+
+ public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String PHOTO = "photo";
+ }
+
+ protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns {
+ field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id";
+ field public static final deprecated java.lang.String PHOTO_URI = "photo_uri";
+ field public static final deprecated java.lang.String SORT_INDEX = "sort_index";
+ field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id";
+ field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1";
+ field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2";
+ field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3";
+ field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4";
+ }
+
+ public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
+ field public static final deprecated android.net.Uri CONTENT_LIMIT_URI;
+ field public static final deprecated android.net.Uri CONTENT_PHOTO_URI;
+ field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
+ field public static final deprecated android.net.Uri CONTENT_URI;
+ field public static final deprecated java.lang.String MAX_ITEMS = "max_items";
+ }
+
+ public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
+ field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
+ field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
+ }
+
+ protected static abstract deprecated interface ContactsContract.StreamItemsColumns {
+ field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name";
+ field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type";
+ field public static final deprecated java.lang.String COMMENTS = "comments";
+ field public static final deprecated java.lang.String CONTACT_ID = "contact_id";
+ field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
+ field public static final deprecated java.lang.String DATA_SET = "data_set";
+ field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id";
+ field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
+ field public static final deprecated java.lang.String RES_ICON = "icon";
+ field public static final deprecated java.lang.String RES_LABEL = "label";
+ field public static final deprecated java.lang.String RES_PACKAGE = "res_package";
+ field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1";
+ field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2";
+ field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3";
+ field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4";
+ field public static final deprecated java.lang.String TEXT = "text";
+ field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
+ }
+
public static final class Settings.System extends android.provider.Settings.NameValueTable {
field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
diff --git a/api/system-current.txt b/api/system-current.txt
index 5ecc791..a245a3e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -156,13 +156,10 @@
field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
- field public static final deprecated java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
- field public static final deprecated java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
- field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";
field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL";
field public static final java.lang.String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL";
field public static final java.lang.String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS";
@@ -227,12 +224,9 @@
field public static final java.lang.String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE";
- field public static final deprecated java.lang.String WRITE_PROFILE = "android.permission.WRITE_PROFILE";
field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
- field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
- field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";
field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL";
}
@@ -247,9 +241,7 @@
field public static final java.lang.String PHONE = "android.permission-group.PHONE";
field public static final java.lang.String SENSORS = "android.permission-group.SENSORS";
field public static final java.lang.String SMS = "android.permission-group.SMS";
- field public static final java.lang.String SOCIAL_INFO = "android.permission-group.SOCIAL_INFO";
field public static final java.lang.String STORAGE = "android.permission-group.STORAGE";
- field public static final java.lang.String USER_DICTIONARY = "android.permission-group.USER_DICTIONARY";
}
public final class R {
@@ -4112,79 +4104,6 @@
field public java.lang.String serviceDetails;
}
- public deprecated class AssistContent {
- ctor public AssistContent();
- method public android.content.ClipData getClipData();
- method public android.os.Bundle getExtras();
- method public java.lang.String getStructuredData();
- method public android.net.Uri getWebUri();
- method public boolean isAppProvidedIntent();
- method public void setClipData(android.content.ClipData);
- method public void setIntent(android.content.Intent);
- method public void setStructuredData(java.lang.String);
- method public void setWebUri(android.net.Uri);
- }
-
- public deprecated class AssistStructure {
- ctor public AssistStructure();
- method public android.content.ComponentName getActivityComponent();
- method public int getWindowNodeCount();
- }
-
- public static class AssistStructure.ViewNode {
- method public android.app.AssistStructure.ViewNode getChildAt(int);
- method public int getChildCount();
- method public java.lang.String getClassName();
- method public java.lang.CharSequence getContentDescription();
- method public android.os.Bundle getExtras();
- method public int getHeight();
- method public java.lang.String getHint();
- method public int getId();
- method public java.lang.String getIdEntry();
- method public java.lang.String getIdPackage();
- method public java.lang.String getIdType();
- method public int getLeft();
- method public int getScrollX();
- method public int getScrollY();
- method public java.lang.CharSequence getText();
- method public int getTextBackgroundColor();
- method public int getTextColor();
- method public int getTextSelectionEnd();
- method public int getTextSelectionStart();
- method public float getTextSize();
- method public int getTextStyle();
- method public int getTop();
- method public int getVisibility();
- method public int getWidth();
- method public boolean isAccessibilityFocused();
- method public boolean isActivated();
- method public boolean isAssistBlocked();
- method public boolean isCheckable();
- method public boolean isChecked();
- method public boolean isClickable();
- method public boolean isContextClickable();
- method public boolean isEnabled();
- method public boolean isFocusable();
- method public boolean isFocused();
- method public boolean isLongClickable();
- method public boolean isSelected();
- field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
- field public static final int TEXT_STYLE_BOLD = 1; // 0x1
- field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
- field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8
- field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
- }
-
- public static class AssistStructure.WindowNode {
- method public int getDisplayId();
- method public int getHeight();
- method public int getLeft();
- method public android.app.AssistStructure.ViewNode getRootViewNode();
- method public java.lang.CharSequence getTitle();
- method public int getTop();
- method public int getWidth();
- }
-
public class BroadcastOptions {
method public static android.app.BroadcastOptions makeBasic();
method public void setTemporaryAppWhitelistDuration(long);
@@ -5803,7 +5722,6 @@
field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
- field public static final java.lang.String ACTION_READY_FOR_USER_INITIALIZATION = "android.app.action.READY_FOR_USER_INITIALIZATION";
field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
@@ -5815,7 +5733,6 @@
method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
method public void addUserRestriction(android.content.ComponentName, java.lang.String);
method public void clearCrossProfileIntentFilters(android.content.ComponentName);
- method public void clearDeviceInitializerApp(android.content.ComponentName);
method public void clearDeviceOwnerApp(java.lang.String);
method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
method public void clearProfileOwner(android.content.ComponentName);
@@ -5873,7 +5790,6 @@
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
- method public boolean isDeviceInitializerApp(java.lang.String);
method public boolean isDeviceOwnerApp(java.lang.String);
method public boolean isLockTaskPermitted(java.lang.String);
method public boolean isMasterVolumeMuted(android.content.ComponentName);
@@ -5894,7 +5810,6 @@
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
- method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -5927,7 +5842,6 @@
method public void setSystemUpdatePolicy(android.content.ComponentName, android.app.admin.SystemUpdatePolicy);
method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
- method public boolean setUserEnabled(android.content.ComponentName);
method public void setUserIcon(android.content.ComponentName, android.graphics.Bitmap);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
@@ -5958,12 +5872,6 @@
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
field public static final deprecated java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
- field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM";
field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
@@ -6029,22 +5937,87 @@
package android.app.assist {
- public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable {
- ctor public AssistContent(android.os.Parcel);
+ public deprecated class AssistContent implements android.os.Parcelable {
+ ctor public AssistContent();
method public int describeContents();
+ method public android.content.ClipData getClipData();
+ method public android.os.Bundle getExtras();
method public android.content.Intent getIntent();
+ method public java.lang.String getStructuredData();
+ method public android.net.Uri getWebUri();
+ method public boolean isAppProvidedIntent();
+ method public void setClipData(android.content.ClipData);
+ method public void setIntent(android.content.Intent);
+ method public void setStructuredData(java.lang.String);
+ method public void setWebUri(android.net.Uri);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR;
}
- public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable {
+ public class AssistStructure implements android.os.Parcelable {
ctor public AssistStructure();
method public int describeContents();
- method public android.app.AssistStructure.WindowNode getWindowNodeAt(int);
+ method public android.content.ComponentName getActivityComponent();
+ method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int);
+ method public int getWindowNodeCount();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR;
}
+ public static class AssistStructure.ViewNode {
+ method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
+ method public int getChildCount();
+ method public java.lang.String getClassName();
+ method public java.lang.CharSequence getContentDescription();
+ method public android.os.Bundle getExtras();
+ method public int getHeight();
+ method public java.lang.String getHint();
+ method public int getId();
+ method public java.lang.String getIdEntry();
+ method public java.lang.String getIdPackage();
+ method public java.lang.String getIdType();
+ method public int getLeft();
+ method public int getScrollX();
+ method public int getScrollY();
+ method public java.lang.CharSequence getText();
+ method public int getTextBackgroundColor();
+ method public int getTextColor();
+ method public int getTextSelectionEnd();
+ method public int getTextSelectionStart();
+ method public float getTextSize();
+ method public int getTextStyle();
+ method public int getTop();
+ method public int getVisibility();
+ method public int getWidth();
+ method public boolean isAccessibilityFocused();
+ method public boolean isActivated();
+ method public boolean isAssistBlocked();
+ method public boolean isCheckable();
+ method public boolean isChecked();
+ method public boolean isClickable();
+ method public boolean isContextClickable();
+ method public boolean isEnabled();
+ method public boolean isFocusable();
+ method public boolean isFocused();
+ method public boolean isLongClickable();
+ method public boolean isSelected();
+ field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
+ field public static final int TEXT_STYLE_BOLD = 1; // 0x1
+ field public static final int TEXT_STYLE_ITALIC = 2; // 0x2
+ field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8
+ field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4
+ }
+
+ public static class AssistStructure.WindowNode {
+ method public int getDisplayId();
+ method public int getHeight();
+ method public int getLeft();
+ method public android.app.assist.AssistStructure.ViewNode getRootViewNode();
+ method public java.lang.CharSequence getTitle();
+ method public int getTop();
+ method public int getWidth();
+ }
+
}
package android.app.backup {
@@ -7447,6 +7420,7 @@
method public android.content.Context getContext();
method public final android.os.IBinder getSyncAdapterBinder();
method public abstract void onPerformSync(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.ContentProviderClient, android.content.SyncResult);
+ method public void onSecurityException(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.SyncResult);
method public void onSyncCanceled();
method public void onSyncCanceled(java.lang.Thread);
field public static final deprecated int LOG_SYNC_DETAILS = 2743; // 0xab7
@@ -12645,7 +12619,6 @@
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void invalidateSelf();
method public boolean isAutoMirrored();
- method public boolean isDither();
method public boolean isFilterBitmap();
method public boolean isStateful();
method public final boolean isVisible();
@@ -12665,7 +12638,7 @@
method public void setChangingConfigurations(int);
method public abstract void setColorFilter(android.graphics.ColorFilter);
method public void setColorFilter(int, android.graphics.PorterDuff.Mode);
- method public void setDither(boolean);
+ method public deprecated void setDither(boolean);
method public void setFilterBitmap(boolean);
method public void setHotspot(float, float);
method public void setHotspotBounds(int, int, int, int);
@@ -13850,7 +13823,6 @@
field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
- field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3; // 0x3
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
field public static final int LENS_FACING_BACK = 1; // 0x1
@@ -14203,6 +14175,7 @@
}
public final class StreamConfigurationMap {
+ method public android.util.Size[] getHighResolutionOutputSizes(int);
method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges();
method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size);
method public android.util.Size[] getHighSpeedVideoSizes();
@@ -19722,7 +19695,6 @@
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
method public void onLost(android.net.Network);
- method public void onPreCheck(android.net.Network);
}
public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -19873,6 +19845,7 @@
method public boolean hasTransport(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
+ field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
field public static final int NET_CAPABILITY_CBS = 5; // 0x5
field public static final int NET_CAPABILITY_DUN = 2; // 0x2
field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
@@ -19887,6 +19860,7 @@
field public static final int NET_CAPABILITY_RCS = 8; // 0x8
field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
+ field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
@@ -20841,6 +20815,8 @@
public class ScanResult implements android.os.Parcelable {
method public int describeContents();
+ method public boolean is80211mcResponder();
+ method public boolean isPasspointNetwork();
method public void writeToParcel(android.os.Parcel, int);
field public java.lang.String BSSID;
field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
@@ -20848,18 +20824,19 @@
field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+ field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L
+ field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L
field public java.lang.String SSID;
field public java.lang.String capabilities;
field public int centerFreq0;
field public int centerFreq1;
field public int channelWidth;
+ field public long flags;
field public int frequency;
- field public boolean is80211McRTTResponder;
field public int level;
- field public java.lang.String operatorFriendlyName;
- field public boolean passpointNetwork;
+ field public java.lang.CharSequence operatorFriendlyName;
field public long timestamp;
- field public java.lang.String venueName;
+ field public java.lang.CharSequence venueName;
}
public final class SupplicantState extends java.lang.Enum implements android.os.Parcelable {
@@ -20909,7 +20886,7 @@
field public java.lang.String preSharedKey;
field public int priority;
field public java.lang.String providerFriendlyName;
- field public java.util.HashSet<java.lang.Long> roamingConsortiumIds;
+ field public java.lang.Long[] roamingConsortiumIds;
field public int status;
field public java.lang.String[] wepKeys;
field public int wepTxKeyIndex;
@@ -20986,7 +20963,7 @@
method public java.lang.String getAnonymousIdentity();
method public java.security.cert.X509Certificate getCaCertificate();
method public java.security.cert.X509Certificate getClientCertificate();
- method public java.lang.String getDomainSubjectMatch();
+ method public java.lang.String getDomainSuffixMatch();
method public int getEapMethod();
method public java.lang.String getIdentity();
method public java.lang.String getPassword();
@@ -25622,6 +25599,7 @@
method public deprecated void setUserRestriction(java.lang.String, boolean);
method public deprecated void setUserRestrictions(android.os.Bundle);
method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
+ field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
@@ -27534,10 +27512,6 @@
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final deprecated class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp";
field public static final java.lang.String DISPLAY_NAME = "display_name";
@@ -27853,10 +27827,6 @@
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
@@ -27927,56 +27897,6 @@
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String PHOTO = "photo";
- }
-
- protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final deprecated java.lang.String PHOTO_URI = "photo_uri";
- field public static final deprecated java.lang.String SORT_INDEX = "sort_index";
- field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final deprecated android.net.Uri CONTENT_LIMIT_URI;
- field public static final deprecated android.net.Uri CONTENT_PHOTO_URI;
- field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final deprecated android.net.Uri CONTENT_URI;
- field public static final deprecated java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract deprecated interface ContactsContract.StreamItemsColumns {
- field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name";
- field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final deprecated java.lang.String COMMENTS = "comments";
- field public static final deprecated java.lang.String CONTACT_ID = "contact_id";
- field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final deprecated java.lang.String DATA_SET = "data_set";
- field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final deprecated java.lang.String RES_ICON = "icon";
- field public static final deprecated java.lang.String RES_LABEL = "label";
- field public static final deprecated java.lang.String RES_PACKAGE = "res_package";
- field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1";
- field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2";
- field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3";
- field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4";
- field public static final deprecated java.lang.String TEXT = "text";
- field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
@@ -28643,6 +28563,7 @@
field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+ field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -30663,8 +30584,7 @@
method public final void notifyCarrierNetworkChange(boolean);
method public android.os.IBinder onBind(android.content.Intent);
method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
- field public static final java.lang.String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService";
- field public static final java.lang.String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService";
+ field public static final java.lang.String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
}
public final class MessagePdu implements android.os.Parcelable {
@@ -38926,10 +38846,6 @@
method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float);
}
- public abstract deprecated class ViewAssistStructure extends android.view.ViewStructure {
- ctor public ViewAssistStructure();
- }
-
public class ViewConfiguration {
ctor public deprecated ViewConfiguration();
method public static android.view.ViewConfiguration get(android.content.Context);
@@ -39311,7 +39227,7 @@
ctor public ViewStructure();
method public abstract int addChildCount(int);
method public abstract void asyncCommit();
- method public abstract android.view.ViewAssistStructure asyncNewChild(int);
+ method public abstract android.view.ViewStructure asyncNewChild(int);
method public abstract int getChildCount();
method public abstract android.os.Bundle getExtras();
method public abstract java.lang.CharSequence getHint();
@@ -39319,7 +39235,7 @@
method public abstract int getTextSelectionEnd();
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
- method public abstract android.view.ViewAssistStructure newChild(int);
+ method public abstract android.view.ViewStructure newChild(int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setCheckable(boolean);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 2e6c685..7fc927b 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -117,6 +117,64 @@
field public static final deprecated java.lang.String URL = "url";
}
+ public static final deprecated class ContactsContract.Contacts.StreamItems {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
+ }
+
+ public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
+ }
+
+ public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String PHOTO = "photo";
+ }
+
+ protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns {
+ field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id";
+ field public static final deprecated java.lang.String PHOTO_URI = "photo_uri";
+ field public static final deprecated java.lang.String SORT_INDEX = "sort_index";
+ field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id";
+ field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1";
+ field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2";
+ field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3";
+ field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4";
+ }
+
+ public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
+ field public static final deprecated android.net.Uri CONTENT_LIMIT_URI;
+ field public static final deprecated android.net.Uri CONTENT_PHOTO_URI;
+ field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
+ field public static final deprecated android.net.Uri CONTENT_URI;
+ field public static final deprecated java.lang.String MAX_ITEMS = "max_items";
+ }
+
+ public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns {
+ field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
+ field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
+ field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
+ }
+
+ protected static abstract deprecated interface ContactsContract.StreamItemsColumns {
+ field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name";
+ field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type";
+ field public static final deprecated java.lang.String COMMENTS = "comments";
+ field public static final deprecated java.lang.String CONTACT_ID = "contact_id";
+ field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
+ field public static final deprecated java.lang.String DATA_SET = "data_set";
+ field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id";
+ field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
+ field public static final deprecated java.lang.String RES_ICON = "icon";
+ field public static final deprecated java.lang.String RES_LABEL = "label";
+ field public static final deprecated java.lang.String RES_PACKAGE = "res_package";
+ field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1";
+ field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2";
+ field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3";
+ field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4";
+ field public static final deprecated java.lang.String TEXT = "text";
+ field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
+ }
+
public static final class Settings.System extends android.provider.Settings.NameValueTable {
field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
diff --git a/cmds/hid/Android.mk b/cmds/hid/Android.mk
new file mode 100644
index 0000000..ff3691d
--- /dev/null
+++ b/cmds/hid/Android.mk
@@ -0,0 +1,18 @@
+# Copyright 2015 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := hid
+LOCAL_JNI_SHARED_LIBRARIES := libhidcommand_jni
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := hid
+LOCAL_SRC_FILES := hid
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := EXECUTABLES
+include $(BUILD_PREBUILT)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/cmds/hid/MODULE_LICENSE_APACHE2 b/cmds/hid/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/hid/MODULE_LICENSE_APACHE2
diff --git a/cmds/hid/NOTICE b/cmds/hid/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/cmds/hid/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-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.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cmds/hid/hid b/cmds/hid/hid
new file mode 100755
index 0000000..2359fcd
--- /dev/null
+++ b/cmds/hid/hid
@@ -0,0 +1,8 @@
+#!/system/bin/sh
+#
+# Script to start "hid" on the device, which has a very rudimentary
+# shell.
+#
+base=/system
+export CLASSPATH=$base/framework/hid.jar
+exec app_process $base/bin com.android.commands.hid.Hid "$@"
diff --git a/cmds/hid/jni/Android.mk b/cmds/hid/jni/Android.mk
new file mode 100644
index 0000000..8163a9d
--- /dev/null
+++ b/cmds/hid/jni/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ com_android_commands_hid_Device.cpp
+
+LOCAL_C_INCLUDES := \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/core/jni
+
+LOCAL_SHARED_LIBRARIES := \
+ libandroid_runtime \
+ liblog \
+ libnativehelper \
+ libutils
+
+LOCAL_MODULE := libhidcommand_jni
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += -Wall
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
new file mode 100644
index 0000000..4278e7d
--- /dev/null
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "HidCommandDevice"
+
+#include "com_android_commands_hid_Device.h"
+
+#include <linux/uhid.h>
+
+#include <fcntl.h>
+#include <cstdio>
+#include <cstring>
+#include <memory>
+#include <unistd.h>
+
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
+#include <android_os_MessageQueue.h>
+#include <core_jni_helpers.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <ScopedPrimitiveArray.h>
+#include <ScopedUtfChars.h>
+#include <utils/Log.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace uhid {
+
+static const char* UHID_PATH = "/dev/uhid";
+static const size_t UHID_MAX_NAME_LENGTH = 128;
+
+static struct {
+ jmethodID onDeviceOpen;
+ jmethodID onDeviceError;
+} gDeviceCallbackClassInfo;
+
+static int handleLooperEvents(int fd, int events, void* data) {
+ Device* d = reinterpret_cast<Device*>(data);
+ return d->handleEvents(events);
+}
+
+static void checkAndClearException(JNIEnv* env, const char* methodName) {
+ if (env->ExceptionCheck()) {
+ ALOGE("An exception was thrown by callback '%s'.", methodName);
+ LOGE_EX(env);
+ env->ExceptionClear();
+ }
+}
+
+DeviceCallback::DeviceCallback(JNIEnv* env, jobject callback) :
+ mCallbackObject(env->NewGlobalRef(callback)) { }
+
+DeviceCallback::~DeviceCallback() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->DeleteGlobalRef(mCallbackObject);
+}
+
+void DeviceCallback::onDeviceError() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceError);
+ checkAndClearException(env, "onDeviceError");
+}
+
+void DeviceCallback::onDeviceOpen() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOpen);
+ checkAndClearException(env, "onDeviceOpen");
+}
+
+Device* Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
+ std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
+ std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) {
+
+ int fd = ::open(UHID_PATH, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ ALOGE("Failed to open uhid: %s", strerror(errno));
+ return nullptr;
+ }
+
+ struct uhid_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_CREATE;
+ strncpy((char*)ev.u.create.name, name, UHID_MAX_NAME_LENGTH);
+ ev.u.create.rd_data = descriptor.get();
+ ev.u.create.rd_size = descriptorSize;
+ ev.u.create.bus = BUS_BLUETOOTH;
+ ev.u.create.vendor = vid;
+ ev.u.create.product = pid;
+ ev.u.create.version = 0;
+ ev.u.create.country = 0;
+
+ errno = 0;
+ ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev)));
+ if (ret < 0 || ret != sizeof(ev)) {
+ ::close(fd);
+ ALOGE("Failed to create uhid node: %s", strerror(errno));
+ return nullptr;
+ }
+
+ // Wait for the device to actually be created.
+ ret = TEMP_FAILURE_RETRY(::read(fd, &ev, sizeof(ev)));
+ if (ret < 0 || ev.type != UHID_START) {
+ ::close(fd);
+ ALOGE("uhid node failed to start: %s", strerror(errno));
+ return nullptr;
+ }
+
+ return new Device(id, fd, std::move(callback), looper);
+}
+
+Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) :
+ mId(id), mFd(fd), mDeviceCallback(std::move(callback)), mLooper(looper) {
+ looper->addFd(fd, 0, Looper::EVENT_INPUT, handleLooperEvents, reinterpret_cast<void*>(this));
+}
+
+Device::~Device() {
+ mLooper->removeFd(mFd);
+ struct uhid_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_DESTROY;
+ TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev)));
+ ::close(mFd);
+ mFd = -1;
+}
+
+void Device::sendReport(uint8_t* report, size_t reportSize) {
+ struct uhid_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_INPUT;
+ ev.u.input.size = reportSize;
+ memcpy(&ev.u.input.data, report, reportSize);
+ ssize_t ret = TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev)));
+ if (ret < 0 || ret != sizeof(ev)) {
+ ALOGE("Failed to send hid event: %s", strerror(errno));
+ }
+}
+
+int Device::handleEvents(int events) {
+ if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
+ ALOGE("uhid node was closed or an error occurred. events=0x%x", events);
+ mDeviceCallback->onDeviceError();
+ return 0;
+ }
+ struct uhid_event ev;
+ ssize_t ret = TEMP_FAILURE_RETRY(::read(mFd, &ev, sizeof(ev)));
+ if (ret < 0) {
+ ALOGE("Failed to read from uhid node: %s", strerror(errno));
+ mDeviceCallback->onDeviceError();
+ return 0;
+ }
+
+ if (ev.type == UHID_OPEN) {
+ mDeviceCallback->onDeviceOpen();
+ }
+
+ return 1;
+}
+
+} // namespace uhid
+
+std::unique_ptr<uint8_t[]> getData(JNIEnv* env, jbyteArray javaArray, size_t& outSize) {
+ ScopedByteArrayRO scopedArray(env, javaArray);
+ outSize = scopedArray.size();
+ std::unique_ptr<uint8_t[]> data(new uint8_t[outSize]);
+ for (size_t i = 0; i < outSize; i++) {
+ data[i] = static_cast<uint8_t>(scopedArray[i]);
+ }
+ return data;
+}
+
+static jlong openDevice(JNIEnv* env, jclass clazz, jstring rawName, jint id, jint vid, jint pid,
+ jbyteArray rawDescriptor, jobject queue, jobject callback) {
+ ScopedUtfChars name(env, rawName);
+ if (name.c_str() == nullptr) {
+ return 0;
+ }
+
+ size_t size;
+ std::unique_ptr<uint8_t[]> desc = getData(env, rawDescriptor, size);
+
+ std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
+ sp<Looper> looper = android_os_MessageQueue_getMessageQueue(env, queue)->getLooper();
+
+ uhid::Device* d = uhid::Device::open(
+ id, reinterpret_cast<const char*>(name.c_str()), vid, pid,
+ std::move(desc), size, std::move(cb), std::move(looper));
+ return reinterpret_cast<jlong>(d);
+}
+
+static void sendReport(JNIEnv* env, jclass clazz, jlong ptr,jbyteArray rawReport) {
+ size_t size;
+ std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size);
+ uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
+ if (d) {
+ d->sendReport(report.get(), size);
+ }
+}
+
+static void closeDevice(JNIEnv* env, jclass clazz, jlong ptr) {
+ uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
+ if (d) {
+ delete d;
+ }
+}
+
+static JNINativeMethod sMethods[] = {
+ { "nativeOpenDevice",
+ "(Ljava/lang/String;III[BLandroid/os/MessageQueue;"
+ "Lcom/android/commands/hid/Device$DeviceCallback;)J",
+ reinterpret_cast<void*>(openDevice) },
+ { "nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport) },
+ { "nativeCloseDevice", "(J)V", reinterpret_cast<void*>(closeDevice) },
+};
+
+int register_com_android_commands_hid_Device(JNIEnv* env) {
+ jclass clazz = FindClassOrDie(env, "com/android/commands/hid/Device$DeviceCallback");
+ uhid::gDeviceCallbackClassInfo.onDeviceOpen =
+ GetMethodIDOrDie(env, clazz, "onDeviceOpen", "()V");
+ uhid::gDeviceCallbackClassInfo.onDeviceError=
+ GetMethodIDOrDie(env, clazz, "onDeviceError", "()V");
+ return jniRegisterNativeMethods(env, "com/android/commands/hid/Device",
+ sMethods, NELEM(sMethods));
+}
+
+} // namespace android
+
+jint JNI_OnLoad(JavaVM* jvm, void*) {
+ JNIEnv *env = NULL;
+ if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) {
+ return JNI_ERR;
+ }
+
+ if (android::register_com_android_commands_hid_Device(env) < 0 ){
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_6;
+}
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
new file mode 100644
index 0000000..6c5899e
--- /dev/null
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+
+#include <jni.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace uhid {
+
+class DeviceCallback {
+public:
+ DeviceCallback(JNIEnv* env, jobject callback);
+ ~DeviceCallback();
+
+ void onDeviceOpen();
+ void onDeviceError();
+
+private:
+ jobject mCallbackObject;
+};
+
+class Device {
+public:
+ static Device* open(int32_t id, const char* name, int32_t vid, int32_t pid,
+ std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
+ std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+
+ Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+ ~Device();
+
+ void sendReport(uint8_t* report, size_t reportSize);
+ void close();
+
+ int handleEvents(int events);
+
+private:
+ int32_t mId;
+ int mFd;
+ std::unique_ptr<DeviceCallback> mDeviceCallback;
+ sp<Looper> mLooper;
+};
+
+
+} // namespace uhid
+} // namespace android
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
new file mode 100644
index 0000000..dbe883b
--- /dev/null
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.hid;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.internal.os.SomeArgs;
+
+public class Device {
+ private static final String TAG = "HidDevice";
+
+ // Minimum amount of time to wait before sending input events to a device. Even though we're
+ // guaranteed that the device has been created and opened by the input system, there's still a
+ // window in which the system hasn't started reading events out of it. If a stream of events
+ // begins in during this window (like a button down event) and *then* we start reading, we're
+ // liable to ignore the whole stream.
+ private static final int MIN_WAIT_FOR_FIRST_EVENT = 150;
+
+ private static final int MSG_OPEN_DEVICE = 1;
+ private static final int MSG_SEND_REPORT = 2;
+ private static final int MSG_CLOSE_DEVICE = 3;
+
+
+ private final int mId;
+ private final HandlerThread mThread;
+ private final DeviceHandler mHandler;
+ private long mEventTime;
+
+ private final Object mCond = new Object();
+
+ static {
+ System.loadLibrary("hidcommand_jni");
+ }
+
+ private static native long nativeOpenDevice(String name, int id, int vid, int pid,
+ byte[] descriptor, MessageQueue queue, DeviceCallback callback);
+ private static native void nativeSendReport(long ptr, byte[] data);
+ private static native void nativeCloseDevice(long ptr);
+
+ public Device(int id, String name, int vid, int pid, byte[] descriptor, byte[] report) {
+ mId = id;
+ mThread = new HandlerThread("HidDeviceHandler");
+ mThread.start();
+ mHandler = new DeviceHandler(mThread.getLooper());
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = id;
+ args.argi2 = vid;
+ args.argi3 = pid;
+ if (name != null) {
+ args.arg1 = name;
+ } else {
+ args.arg1 = id + ":" + vid + ":" + pid;
+ }
+ args.arg2 = descriptor;
+ args.arg3 = report;
+ mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget();
+ mEventTime = SystemClock.uptimeMillis() + MIN_WAIT_FOR_FIRST_EVENT;
+ }
+
+ public void sendReport(byte[] report) {
+ Message msg = mHandler.obtainMessage(MSG_SEND_REPORT, report);
+ mHandler.sendMessageAtTime(msg, mEventTime);
+ }
+
+ public void addDelay(int delay) {
+ mEventTime += delay;
+ }
+
+ public void close() {
+ Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, mEventTime + 1);
+ try {
+ synchronized (mCond) {
+ mCond.wait();
+ }
+ } catch (InterruptedException ignore) {}
+ }
+
+ private class DeviceHandler extends Handler {
+ private long mPtr;
+ private int mBarrierToken;
+
+ public DeviceHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_OPEN_DEVICE:
+ SomeArgs args = (SomeArgs) msg.obj;
+ mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3,
+ (byte[]) args.arg2, getLooper().myQueue(), new DeviceCallback());
+ nativeSendReport(mPtr, (byte[]) args.arg3);
+ pauseEvents();
+ break;
+ case MSG_SEND_REPORT:
+ if (mPtr != 0) {
+ nativeSendReport(mPtr, (byte[]) msg.obj);
+ } else {
+ Log.e(TAG, "Tried to send report to closed device.");
+ }
+ break;
+ case MSG_CLOSE_DEVICE:
+ if (mPtr != 0) {
+ nativeCloseDevice(mPtr);
+ getLooper().quitSafely();
+ mPtr = 0;
+ } else {
+ Log.e(TAG, "Tried to close already closed device.");
+ }
+ synchronized (mCond) {
+ mCond.notify();
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown device message");
+ }
+ }
+
+ public void pauseEvents() {
+ mBarrierToken = getLooper().myQueue().postSyncBarrier();
+ }
+
+ public void resumeEvents() {
+ getLooper().myQueue().removeSyncBarrier(mBarrierToken);
+ mBarrierToken = 0;
+ }
+ }
+
+ private class DeviceCallback {
+ public void onDeviceOpen() {
+ mHandler.resumeEvents();
+ }
+
+ public void onDeviceError() {
+ Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
+ msg.setAsynchronous(true);
+ msg.sendToTarget();
+ }
+ }
+}
diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java
new file mode 100644
index 0000000..c6a37bd
--- /dev/null
+++ b/cmds/hid/src/com/android/commands/hid/Event.java
@@ -0,0 +1,255 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.hid;
+
+import android.util.JsonReader;
+import android.util.JsonToken;
+import android.util.Log;
+
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class Event {
+ private static final String TAG = "HidEvent";
+
+ public static final String COMMAND_REGISTER = "register";
+ public static final String COMMAND_DELAY = "delay";
+ public static final String COMMAND_REPORT = "report";
+
+ private int mId;
+ private String mCommand;
+ private String mName;
+ private byte[] mDescriptor;
+ private int mVid;
+ private int mPid;
+ private byte[] mReport;
+ private int mDuration;
+
+ public int getId() {
+ return mId;
+ }
+
+ public String getCommand() {
+ return mCommand;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public byte[] getDescriptor() {
+ return mDescriptor;
+ }
+
+ public int getVendorId() {
+ return mVid;
+ }
+
+ public int getProductId() {
+ return mPid;
+ }
+
+ public byte[] getReport() {
+ return mReport;
+ }
+
+ public int getDuration() {
+ return mDuration;
+ }
+
+ public String toString() {
+ return "Event{id=" + mId
+ + ", command=" + String.valueOf(mCommand)
+ + ", name=" + String.valueOf(mName)
+ + ", descriptor=" + Arrays.toString(mDescriptor)
+ + ", vid=" + mVid
+ + ", pid=" + mPid
+ + ", report=" + Arrays.toString(mReport)
+ + ", duration=" + mDuration
+ + "}";
+ }
+
+ private static class Builder {
+ private Event mEvent;
+
+ public Builder() {
+ mEvent = new Event();
+ }
+
+ public void setId(int id) {
+ mEvent.mId = id;
+ }
+
+ private void setCommand(String command) {
+ mEvent.mCommand = command;
+ }
+
+ public void setName(String name) {
+ mEvent.mName = name;
+ }
+
+ public void setDescriptor(byte[] descriptor) {
+ mEvent.mDescriptor = descriptor;
+ }
+
+ public void setReport(byte[] report) {
+ mEvent.mReport = report;
+ }
+
+ public void setVid(int vid) {
+ mEvent.mVid = vid;
+ }
+
+ public void setPid(int pid) {
+ mEvent.mPid = pid;
+ }
+
+ public void setDuration(int duration) {
+ mEvent.mDuration = duration;
+ }
+
+ public Event build() {
+ if (mEvent.mId == -1) {
+ throw new IllegalStateException("No event id");
+ } else if (mEvent.mCommand == null) {
+ throw new IllegalStateException("Event does not contain a command");
+ }
+ if (COMMAND_REGISTER.equals(mEvent.mCommand)) {
+ if (mEvent.mDescriptor == null) {
+ throw new IllegalStateException("Device registration is missing descriptor");
+ }
+ } else if (COMMAND_DELAY.equals(mEvent.mCommand)) {
+ if (mEvent.mDuration <= 0) {
+ throw new IllegalStateException("Delay has missing or invalid duration");
+ }
+ } else if (COMMAND_REPORT.equals(mEvent.mCommand)) {
+ if (mEvent.mReport == null) {
+ throw new IllegalStateException("Report command is missing report data");
+ }
+ }
+ return mEvent;
+ }
+ }
+
+ public static class Reader {
+ private JsonReader mReader;
+
+ public Reader(InputStreamReader in) {
+ mReader = new JsonReader(in);
+ mReader.setLenient(true);
+ }
+
+ public Event getNextEvent() throws IOException {
+ Event e = null;
+ while (e == null && mReader.peek() != JsonToken.END_DOCUMENT) {
+ Event.Builder eb = new Event.Builder();
+ try {
+ mReader.beginObject();
+ while (mReader.hasNext()) {
+ String name = mReader.nextName();
+ switch (name) {
+ case "id":
+ eb.setId(readInt());
+ break;
+ case "command":
+ eb.setCommand(mReader.nextString());
+ break;
+ case "descriptor":
+ eb.setDescriptor(readData());
+ break;
+ case "name":
+ eb.setName(mReader.nextString());
+ break;
+ case "vid":
+ eb.setVid(readInt());
+ break;
+ case "pid":
+ eb.setPid(readInt());
+ break;
+ case "report":
+ eb.setReport(readData());
+ break;
+ case "duration":
+ eb.setDuration(readInt());
+ break;
+ default:
+ mReader.skipValue();
+ }
+ }
+ mReader.endObject();
+ } catch (IllegalStateException ex) {
+ error("Error reading in object, ignoring.", ex);
+ consumeRemainingElements();
+ mReader.endObject();
+ continue;
+ }
+ e = eb.build();
+ }
+
+ return e;
+ }
+
+ private byte[] readData() throws IOException {
+ ArrayList<Integer> data = new ArrayList<Integer>();
+ try {
+ mReader.beginArray();
+ while (mReader.hasNext()) {
+ data.add(Integer.decode(mReader.nextString()));
+ }
+ mReader.endArray();
+ } catch (IllegalStateException|NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endArray();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ byte[] rawData = new byte[data.size()];
+ for (int i = 0; i < data.size(); i++) {
+ int d = data.get(i);
+ if ((d & 0xFF) != d) {
+ throw new IllegalStateException("Invalid data, all values must be byte-sized");
+ }
+ rawData[i] = (byte)d;
+ }
+ return rawData;
+ }
+
+ private int readInt() throws IOException {
+ String val = mReader.nextString();
+ return Integer.decode(val);
+ }
+
+ private void consumeRemainingElements() throws IOException {
+ while (mReader.hasNext()) {
+ mReader.skipValue();
+ }
+ }
+ }
+
+ private static void error(String msg) {
+ error(msg, null);
+ }
+
+ private static void error(String msg, Exception e) {
+ System.out.println(msg);
+ Log.e(TAG, msg);
+ if (e != null) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ }
+ }
+}
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
new file mode 100644
index 0000000..976a782
--- /dev/null
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+package com.android.commands.hid;
+
+import android.os.SystemClock;
+import android.util.JsonReader;
+import android.util.JsonToken;
+import android.util.Log;
+import android.util.SparseArray;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+public class Hid {
+ private static final String TAG = "HID";
+
+ private final Event.Reader mReader;
+ private final SparseArray<Device> mDevices;
+
+ private static void usage() {
+ error("Usage: hid [FILE]");
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 1) {
+ usage();
+ System.exit(1);
+ }
+
+ InputStream stream = null;
+ try {
+ if (args[0].equals("-")) {
+ stream = System.in;
+ } else {
+ File f = new File(args[0]);
+ stream = new FileInputStream(f);
+ }
+ (new Hid(stream)).run();
+ } catch (Exception e) {
+ error("HID injection failed.", e);
+ System.exit(1);
+ } finally {
+ IoUtils.closeQuietly(stream);
+ }
+ }
+
+ private Hid(InputStream in) {
+ mDevices = new SparseArray<Device>();
+ try {
+ mReader = new Event.Reader(new InputStreamReader(in, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void run() {
+ try {
+ Event e = null;
+ while ((e = mReader.getNextEvent()) != null) {
+ process(e);
+ }
+ } catch (IOException ex) {
+ error("Error reading in events.", ex);
+ }
+
+ for (int i = 0; i < mDevices.size(); i++) {
+ mDevices.valueAt(i).close();
+ }
+ }
+
+
+ private void process(Event e) {
+ final int index = mDevices.indexOfKey(e.getId());
+ if (index >= 0) {
+ Device d = mDevices.valueAt(index);
+ if (Event.COMMAND_DELAY.equals(e.getCommand())) {
+ d.addDelay(e.getDuration());
+ } else if (Event.COMMAND_REPORT.equals(e.getCommand())) {
+ d.sendReport(e.getReport());
+ } else {
+ error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
+ }
+ } else {
+ registerDevice(e);
+ }
+ }
+
+ private void registerDevice(Event e) {
+ if (!Event.COMMAND_REGISTER.equals(e.getCommand())) {
+ throw new IllegalStateException(
+ "Tried to send command \"" + e.getCommand() + "\" to an unregistered device!");
+ }
+ int id = e.getId();
+ Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(),
+ e.getDescriptor(), e.getReport());
+ mDevices.append(id, d);
+ }
+
+ private static void error(String msg) {
+ error(msg, null);
+ }
+
+ private static void error(String msg, Exception e) {
+ System.out.println(msg);
+ Log.e(TAG, msg);
+ if (e != null) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ }
+ }
+}
diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java
index 64f023f..fb050e5 100644
--- a/cmds/wm/src/com/android/commands/wm/Wm.java
+++ b/cmds/wm/src/com/android/commands/wm/Wm.java
@@ -54,6 +54,7 @@
" wm density [reset|DENSITY]\n" +
" wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
" wm scaling [off|auto]\n" +
+ " wm screen-capture [userId] [true|false]\n" +
"\n" +
"wm size: return or override display size.\n" +
" width and height in pixels unless suffixed with 'dp'.\n" +
@@ -62,7 +63,9 @@
"\n" +
"wm overscan: set overscan area for display.\n" +
"\n" +
- "wm scaling: set display scaling mode.\n"
+ "wm scaling: set display scaling mode.\n" +
+ "\n" +
+ "wm screen-capture: enable/disable screen capture.\n"
);
}
@@ -85,16 +88,39 @@
runDisplayOverscan();
} else if (op.equals("scaling")) {
runDisplayScaling();
+ } else if (op.equals("screen-capture")) {
+ runSetScreenCapture();
} else {
showError("Error: unknown command '" + op + "'");
return;
}
}
+ private void runSetScreenCapture() throws Exception {
+ String userIdStr = nextArg();
+ String enableStr = nextArg();
+ int userId;
+ boolean disable;
+
+ try {
+ userId = Integer.parseInt(userIdStr);
+ } catch (NumberFormatException e) {
+ System.err.println("Error: bad number " + e);
+ return;
+ }
+
+ disable = !Boolean.parseBoolean(enableStr);
+
+ try {
+ mWm.setScreenCaptureDisabled(userId, disable);
+ } catch (RemoteException e) {
+ System.err.println("Error: Can't set screen capture " + e);
+ }
+ }
+
private void runDisplaySize() throws Exception {
String size = nextArg();
int w, h;
- boolean scale = true;
if (size == null) {
Point initialSize = new Point();
Point baseSize = new Point();
@@ -181,7 +207,6 @@
private void runDisplayOverscan() throws Exception {
String overscanStr = nextArgRequired();
Rect rect = new Rect();
- int density;
if ("reset".equals(overscanStr)) {
rect.set(0, 0, 0, 0);
} else {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 993b53d..3001c2c 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -209,7 +209,8 @@
/**
* Bundle key used to supply the last time the credentials of the account
* were authenticated successfully. Time is specified in milliseconds since
- * epoch.
+ * epoch. Associated time is updated on successful authentication of account
+ * on adding account, confirming credentials, or updating credentials.
*/
public static final String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime";
@@ -651,18 +652,25 @@
}
/**
- * Adds an account directly to the AccountManager. Normally used by sign-up
+ * Adds an account directly to the AccountManager. Normally used by sign-up
* wizards associated with authenticators, not directly by applications.
- *
+ * <p>Calling this method does not update the last authenticated timestamp,
+ * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call
+ * {@link #notifyAccountAuthenticated(Account)} after getting success.
+ * However, if this method is called when it is triggered by addAccount() or
+ * addAccountAsUser() or similar functions, then there is no need to update
+ * timestamp manually as it is updated automatically by framework on
+ * successful completion of the mentioned functions.
* <p>It is safe to call this method from the main thread.
* <p>This method requires the caller to have a signature match with the
* authenticator that owns the specified account.
*
* @param account The {@link Account} to add
* @param password The password to associate with the account, null for none
- * @param userdata String values to use for the account's userdata, null for none
+ * @param userdata String values to use for the account's userdata, null for
+ * none
* @return True if the account was successfully added, false if the account
- * already exists, the account is null, or another error occurs.
+ * already exists, the account is null, or another error occurs.
*/
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
if (account == null) throw new IllegalArgumentException("account is null");
@@ -976,17 +984,19 @@
}
/**
- * Sets or forgets a saved password. This modifies the local copy of the
- * password used to automatically authenticate the user; it does
- * not change the user's account password on the server. Intended for use
- * by the authenticator, not directly by applications.
- *
+ * Sets or forgets a saved password. This modifies the local copy of the
+ * password used to automatically authenticate the user; it does not change
+ * the user's account password on the server. Intended for use by the
+ * authenticator, not directly by applications.
+ * <p>Calling this method does not update the last authenticated timestamp,
+ * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call
+ * {@link #notifyAccountAuthenticated(Account)} after getting success.
* <p>It is safe to call this method from the main thread.
- *
* <p>This method requires the caller to have a signature match with the
* authenticator that manages the specified account.
*
- * @param account The account whose password is to be set. Cannot be {@code null}.
+ * @param account The account whose password is to be set. Cannot be
+ * {@code null}.
* @param password The password to set, null to clear the password
*/
public void setPassword(final Account account, final String password) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1b4ee2e..e8ab109 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2075,6 +2075,9 @@
"by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
"android:windowActionBar to false in your theme to use a Toolbar instead.");
}
+ // Clear out the MenuInflater to make sure that it is valid for the new Action Bar
+ mMenuInflater = null;
+
ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
mActionBar = tbab;
mWindow.setCallback(tbab.getWrappedWindowCallback());
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
deleted file mode 100644
index ad2ba39..0000000
--- a/core/java/android/app/AssistContent.java
+++ /dev/null
@@ -1,219 +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.
- */
-
-package android.app;
-
-import android.content.ClipData;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Holds information about the content an application is viewing, to hand to an
- * assistant at the user's request. This is filled in by
- * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
- * @deprecated use {@link android.app.assist.AssistContent}.
- */
-@Deprecated
-public class AssistContent {
- private boolean mIsAppProvidedIntent = false;
- private Intent mIntent;
- private String mStructuredData;
- private ClipData mClipData;
- private Uri mUri;
- private final Bundle mExtras;
-
- /**
- * @hide
- * Key name this data structure is stored in the Bundle generated by
- * {@link android.app.Activity#onProvideAssistData}.
- */
- public static final String ASSIST_KEY = "android:assist_content";
-
- /**
- * @hide
- * Retrieve the framework-generated AssistContent that is stored within
- * the Bundle filled in by {@link android.app.Activity#onProvideAssistContent}.
- */
- public static android.app.assist.AssistContent getAssistContent(Bundle assistBundle) {
- return assistBundle.getParcelable(ASSIST_KEY);
- }
-
- public AssistContent() {
- mExtras = new Bundle();
- }
-
- /**
- * @hide
- * Called by {@link android.app.ActivityThread} to set the default Intent based on
- * {@link android.app.Activity#getIntent Activity.getIntent}.
- *
- * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
- * of a web (http or https scheme) URI.</p>
- */
- public void setDefaultIntent(Intent intent) {
- mIntent = intent;
- setWebUri(null);
- if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
- Uri uri = intent.getData();
- if (uri != null) {
- if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
- setWebUri(uri);
- }
- }
- }
- }
-
- /**
- * Sets the Intent associated with the content, describing the current top-level context of
- * the activity. If this contains a reference to a piece of data related to the activity,
- * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
- * service can access it.
- */
- public void setIntent(Intent intent) {
- mIsAppProvidedIntent = true;
- mIntent = intent;
- }
-
- /**
- * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
- * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
- * @hide
- */
- public Intent getIntent() {
- return mIntent;
- }
-
- /**
- * Returns whether or not the current Intent was explicitly provided in
- * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
- * the Intent was automatically set based on
- * {@link android.app.Activity#getIntent Activity.getIntent}.
- */
- public boolean isAppProvidedIntent() {
- return mIsAppProvidedIntent;
- }
-
- /**
- * Optional additional content items that are involved with
- * the current UI. Access to this content will be granted to the assistant as if you
- * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
- */
- public void setClipData(ClipData clip) {
- mClipData = clip;
- }
-
- /**
- * Return the current {@link #setClipData}, which you can modify in-place.
- */
- public ClipData getClipData() {
- return mClipData;
- }
-
- /**
- * Sets optional structured data regarding the content being viewed. The provided data
- * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
- * <a href="http://schema.org/">schema.org</a> vocabulary.
- */
- public void setStructuredData(String structuredData) {
- mStructuredData = structuredData;
- }
-
- /**
- * Returns the current {@link #setStructuredData}.
- */
- public String getStructuredData() {
- return mStructuredData;
- }
-
- /**
- * Set a web URI associated with the current data being shown to the user.
- * This URI could be opened in a web browser, or in the app as an
- * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
- * being displayed by it. The URI here should be something that is transportable
- * off the device into other environments to acesss the same data as is currently
- * being shown in the app; if the app does not have such a representation, it should
- * leave the null and only report the local intent and clip data.
- */
- public void setWebUri(Uri uri) {
- mUri = uri;
- }
-
- /**
- * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
- * there is none.
- */
- public Uri getWebUri() {
- return mUri;
- }
-
- /**
- * Return Bundle for extra vendor-specific data that can be modified and examined.
- */
- public Bundle getExtras() {
- return mExtras;
- }
-
- /** @hide */
- public AssistContent(Parcel in) {
- if (in.readInt() != 0) {
- mIntent = Intent.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mClipData = ClipData.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mUri = Uri.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mStructuredData = in.readString();
- }
- mIsAppProvidedIntent = in.readInt() == 1;
- mExtras = in.readBundle();
- }
-
- /** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
- if (mIntent != null) {
- dest.writeInt(1);
- mIntent.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mClipData != null) {
- dest.writeInt(1);
- mClipData.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mUri != null) {
- dest.writeInt(1);
- mUri.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mStructuredData != null) {
- dest.writeInt(1);
- dest.writeString(mStructuredData);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
- dest.writeBundle(mExtras);
- }
-}
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
deleted file mode 100644
index 7f6dae5..0000000
--- a/core/java/android/app/AssistStructure.java
+++ /dev/null
@@ -1,1075 +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.
- */
-
-package android.app;
-
-import android.content.ComponentName;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PooledStringReader;
-import android.os.PooledStringWriter;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewAssistStructure;
-import android.view.ViewRootImpl;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import java.util.ArrayList;
-
-/**
- * Assist data automatically created by the platform's implementation
- * of {@link android.app.Activity#onProvideAssistData}.
- * @deprecated use {@link android.app.assist.AssistStructure}.
- */
-@Deprecated
-public class AssistStructure {
- static final String TAG = "AssistStructure";
-
- /**
- * @hide
- * Key name this data structure is stored in the Bundle generated by
- * {@link android.app.Activity#onProvideAssistData}.
- */
- public static final String ASSIST_KEY = "android:assist_structure";
-
- /** @hide */
- public boolean mHaveData;
-
- ComponentName mActivityComponent;
-
- final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
-
- final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
-
- /** @hide */
- public SendChannel mSendChannel;
- /** @hide */
- public IBinder mReceiveChannel;
-
- Rect mTmpRect = new Rect();
-
- static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
- static final String DESCRIPTOR = "android.app.AssistStructure";
-
- /** @hide */
- public final class SendChannel extends Binder {
- @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- if (code == TRANSACTION_XFER) {
- data.enforceInterface(DESCRIPTOR);
- writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- } else {
- return super.onTransact(code, data, reply, flags);
- }
- }
- }
-
- final static class ViewNodeText {
- CharSequence mText;
- int mTextSelectionStart;
- int mTextSelectionEnd;
- int mTextColor;
- int mTextBackgroundColor;
- float mTextSize;
- int mTextStyle;
- String mHint;
-
- ViewNodeText() {
- }
-
- ViewNodeText(Parcel in) {
- mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- mTextSelectionStart = in.readInt();
- mTextSelectionEnd = in.readInt();
- mTextColor = in.readInt();
- mTextBackgroundColor = in.readInt();
- mTextSize = in.readFloat();
- mTextStyle = in.readInt();
- mHint = in.readString();
- }
-
- void writeToParcel(Parcel out) {
- TextUtils.writeToParcel(mText, out, 0);
- out.writeInt(mTextSelectionStart);
- out.writeInt(mTextSelectionEnd);
- out.writeInt(mTextColor);
- out.writeInt(mTextBackgroundColor);
- out.writeFloat(mTextSize);
- out.writeInt(mTextStyle);
- out.writeString(mHint);
- }
- }
-
- /**
- * Describes a window in the assist data.
- */
- static public class WindowNode {
- final int mX;
- final int mY;
- final int mWidth;
- final int mHeight;
- final CharSequence mTitle;
- final int mDisplayId;
- final ViewNode mRoot;
-
- WindowNode(AssistStructure assist, ViewRootImpl root) {
- View view = root.getView();
- Rect rect = new Rect();
- view.getBoundsOnScreen(rect);
- mX = rect.left - view.getLeft();
- mY = rect.top - view.getTop();
- mWidth = rect.width();
- mHeight = rect.height();
- mTitle = root.getTitle();
- mDisplayId = root.getDisplayId();
- mRoot = new ViewNode();
- ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
- if ((root.getWindowFlags()&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- // This is a secure window, so it doesn't want a screenshot, and that
- // means we should also not copy out its view hierarchy.
- view.onProvideStructure(builder);
- builder.setAssistBlocked(true);
- return;
- }
- view.dispatchProvideStructure(builder);
- }
-
- WindowNode(Parcel in, PooledStringReader preader) {
- mX = in.readInt();
- mY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- mDisplayId = in.readInt();
- mRoot = new ViewNode(in, preader);
- }
-
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- TextUtils.writeToParcel(mTitle, out, 0);
- out.writeInt(mDisplayId);
- mRoot.writeToParcel(out, pwriter);
- }
-
- /**
- * Returns the left edge of the window, in pixels, relative to the left
- * edge of the screen.
- */
- public int getLeft() {
- return mX;
- }
-
- /**
- * Returns the top edge of the window, in pixels, relative to the top
- * edge of the screen.
- */
- public int getTop() {
- return mY;
- }
-
- /**
- * Returns the total width of the window in pixels.
- */
- public int getWidth() {
- return mWidth;
- }
-
- /**
- * Returns the total height of the window in pixels.
- */
- public int getHeight() {
- return mHeight;
- }
-
- /**
- * Returns the title associated with the window, if it has one.
- */
- public CharSequence getTitle() {
- return mTitle;
- }
-
- /**
- * Returns the ID of the display this window is on, for use with
- * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}.
- */
- public int getDisplayId() {
- return mDisplayId;
- }
-
- /**
- * Returns the {@link ViewNode} containing the root content of the window.
- */
- public ViewNode getRootViewNode() {
- return mRoot;
- }
- }
-
- /**
- * Describes a single view in the assist data.
- */
- static public class ViewNode {
- /**
- * Magic value for text color that has not been defined, which is very unlikely
- * to be confused with a real text color.
- */
- public static final int TEXT_COLOR_UNDEFINED = 1;
-
- public static final int TEXT_STYLE_BOLD = 1<<0;
- public static final int TEXT_STYLE_ITALIC = 1<<1;
- public static final int TEXT_STYLE_UNDERLINE = 1<<2;
- public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
-
- int mId;
- String mIdPackage;
- String mIdType;
- String mIdEntry;
- int mX;
- int mY;
- int mScrollX;
- int mScrollY;
- int mWidth;
- int mHeight;
-
- static final int FLAGS_DISABLED = 0x00000001;
- static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
- static final int FLAGS_FOCUSABLE = 0x00000010;
- static final int FLAGS_FOCUSED = 0x00000020;
- static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
- static final int FLAGS_SELECTED = 0x00000040;
- static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
- static final int FLAGS_ACTIVATED = 0x40000000;
- static final int FLAGS_CHECKABLE = 0x00000100;
- static final int FLAGS_CHECKED = 0x00000200;
- static final int FLAGS_CLICKABLE = 0x00004000;
- static final int FLAGS_LONG_CLICKABLE = 0x00200000;
- static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
-
- int mFlags;
-
- String mClassName;
- CharSequence mContentDescription;
-
- ViewNodeText mText;
- Bundle mExtras;
-
- ViewNode[] mChildren;
-
- ViewNode() {
- }
-
- ViewNode(Parcel in, PooledStringReader preader) {
- mId = in.readInt();
- if (mId != 0) {
- mIdEntry = preader.readString();
- if (mIdEntry != null) {
- mIdType = preader.readString();
- mIdPackage = preader.readString();
- } else {
- mIdPackage = mIdType = null;
- }
- } else {
- mIdPackage = mIdType = mIdEntry = null;
- }
- mX = in.readInt();
- mY = in.readInt();
- mScrollX = in.readInt();
- mScrollY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mFlags = in.readInt();
- mClassName = preader.readString();
- mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- if (in.readInt() != 0) {
- mText = new ViewNodeText(in);
- } else {
- mText = null;
- }
- mExtras = in.readBundle();
- final int NCHILDREN = in.readInt();
- if (NCHILDREN > 0) {
- mChildren = new ViewNode[NCHILDREN];
- for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(in, preader);
- }
- } else {
- mChildren = null;
- }
- }
-
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mId);
- if (mId != 0) {
- pwriter.writeString(mIdEntry);
- if (mIdEntry != null) {
- pwriter.writeString(mIdType);
- pwriter.writeString(mIdPackage);
- }
- }
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mScrollX);
- out.writeInt(mScrollY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- out.writeInt(mFlags);
- pwriter.writeString(mClassName);
- TextUtils.writeToParcel(mContentDescription, out, 0);
- if (mText != null) {
- out.writeInt(1);
- mText.writeToParcel(out);
- } else {
- out.writeInt(0);
- }
- out.writeBundle(mExtras);
- if (mChildren != null) {
- final int NCHILDREN = mChildren.length;
- out.writeInt(NCHILDREN);
- for (int i=0; i<NCHILDREN; i++) {
- mChildren[i].writeToParcel(out, pwriter);
- }
- } else {
- out.writeInt(0);
- }
- }
-
- /**
- * Returns the ID associated with this view, as per {@link View#getId() View.getId()}.
- */
- public int getId() {
- return mId;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the package name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdPackage() {
- return mIdPackage;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the type name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdType() {
- return mIdType;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the entry name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdEntry() {
- return mIdEntry;
- }
-
- /**
- * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
- */
- public int getLeft() {
- return mX;
- }
-
- /**
- * Returns the top edge of this view, in pixels, relative to the top edge of its parent.
- */
- public int getTop() {
- return mY;
- }
-
- /**
- * Returns the current X scroll offset of this view, as per
- * {@link android.view.View#getScrollX() View.getScrollX()}.
- */
- public int getScrollX() {
- return mScrollX;
- }
-
- /**
- * Returns the current Y scroll offset of this view, as per
- * {@link android.view.View#getScrollX() View.getScrollY()}.
- */
- public int getScrollY() {
- return mScrollY;
- }
-
- /**
- * Returns the width of this view, in pixels.
- */
- public int getWidth() {
- return mWidth;
- }
-
- /**
- * Returns the height of this view, in pixels.
- */
- public int getHeight() {
- return mHeight;
- }
-
- /**
- * Returns the visibility mode of this view, as per
- * {@link android.view.View#getVisibility() View.getVisibility()}.
- */
- public int getVisibility() {
- return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
- }
-
- /**
- * Returns true if assist data has been blocked starting at this node in the hierarchy.
- */
- public boolean isAssistBlocked() {
- return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
- }
-
- /**
- * Returns true if this node is in an enabled state.
- */
- public boolean isEnabled() {
- return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
- }
-
- /**
- * Returns true if this node is clickable by the user.
- */
- public boolean isClickable() {
- return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
- }
-
- /**
- * Returns true if this node can take input focus.
- */
- public boolean isFocusable() {
- return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
- }
-
- /**
- * Returns true if this node currently had input focus at the time that the
- * structure was collected.
- */
- public boolean isFocused() {
- return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
- }
-
- /**
- * Returns true if this node currently had accessibility focus at the time that the
- * structure was collected.
- */
- public boolean isAccessibilityFocused() {
- return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
- }
-
- /**
- * Returns true if this node represents something that is checkable by the user.
- */
- public boolean isCheckable() {
- return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
- }
-
- /**
- * Returns true if this node is currently in a checked state.
- */
- public boolean isChecked() {
- return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
- }
-
- /**
- * Returns true if this node has currently been selected by the user.
- */
- public boolean isSelected() {
- return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
- }
-
- /**
- * Returns true if this node has currently been activated by the user.
- */
- public boolean isActivated() {
- return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
- }
-
- /**
- * Returns true if this node is something the user can perform a long click/press on.
- */
- public boolean isLongClickable() {
- return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
- }
-
- /**
- * Returns true if this node is something the user can perform a context click on.
- */
- public boolean isContextClickable() {
- return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0;
- }
-
- /**
- * Returns the class name of the node's implementation, indicating its behavior.
- * For example, a button will report "android.widget.Button" meaning it behaves
- * like a {@link android.widget.Button}.
- */
- public String getClassName() {
- return mClassName;
- }
-
- /**
- * Returns any content description associated with the node, which semantically describes
- * its purpose for accessibility and other uses.
- */
- public CharSequence getContentDescription() {
- return mContentDescription;
- }
-
- /**
- * Returns any text associated with the node that is displayed to the user, or null
- * if there is none.
- */
- public CharSequence getText() {
- return mText != null ? mText.mText : null;
- }
-
- /**
- * If {@link #getText()} is non-null, this is where the current selection starts.
- */
- public int getTextSelectionStart() {
- return mText != null ? mText.mTextSelectionStart : -1;
- }
-
- /**
- * If {@link #getText()} is non-null, this is where the current selection starts.
- * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
- * indicating the cursor position.
- */
- public int getTextSelectionEnd() {
- return mText != null ? mText.mTextSelectionEnd : -1;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text color associated with it.
- * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned.
- * Note that the text may also contain style spans that modify the color of specific
- * parts of the text.
- */
- public int getTextColor() {
- return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text background color associated
- * with it.
- * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
- * Note that the text may also contain style spans that modify the color of specific
- * parts of the text.
- */
- public int getTextBackgroundColor() {
- return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text size (in pixels) associated
- * with it.
- * Note that the text may also contain style spans that modify the size of specific
- * parts of the text.
- */
- public float getTextSize() {
- return mText != null ? mText.mTextSize : 0;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text style associated
- * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD},
- * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or
- * {@link #TEXT_STYLE_UNDERLINE}.
- * Note that the text may also contain style spans that modify the style of specific
- * parts of the text.
- */
- public int getTextStyle() {
- return mText != null ? mText.mTextStyle : 0;
- }
-
- /**
- * Return additional hint text associated with the node; this is typically used with
- * a node that takes user input, describing to the user what the input means.
- */
- public String getHint() {
- return mText != null ? mText.mHint : null;
- }
-
- /**
- * Return a Bundle containing optional vendor-specific extension information.
- */
- public Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Return the number of children this node has.
- */
- public int getChildCount() {
- return mChildren != null ? mChildren.length : 0;
- }
-
- /**
- * Return a child of this node, given an index value from 0 to
- * {@link #getChildCount()}-1.
- */
- public ViewNode getChildAt(int index) {
- return mChildren[index];
- }
- }
-
- static class ViewNodeBuilder extends ViewAssistStructure {
- final AssistStructure mAssist;
- final ViewNode mNode;
- final boolean mAsync;
-
- ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) {
- mAssist = assist;
- mNode = node;
- mAsync = async;
- }
-
- @Override
- public void setId(int id, String packageName, String typeName, String entryName) {
- mNode.mId = id;
- mNode.mIdPackage = packageName;
- mNode.mIdType = typeName;
- mNode.mIdEntry = entryName;
- }
-
- @Override
- public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
- mNode.mX = left;
- mNode.mY = top;
- mNode.mScrollX = scrollX;
- mNode.mScrollY = scrollY;
- mNode.mWidth = width;
- mNode.mHeight = height;
- }
-
- @Override
- public void setVisibility(int visibility) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
- }
-
- @Override
- public void setAssistBlocked(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
- | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
- }
-
- @Override
- public void setEnabled(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED)
- | (state ? 0 : ViewNode.FLAGS_DISABLED);
- }
-
- @Override
- public void setClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE)
- | (state ? ViewNode.FLAGS_CLICKABLE : 0);
- }
-
- @Override
- public void setLongClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE)
- | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0);
- }
-
- @Override
- public void setContextClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE)
- | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0);
- }
-
- @Override
- public void setFocusable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
- | (state ? ViewNode.FLAGS_FOCUSABLE : 0);
- }
-
- @Override
- public void setFocused(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED)
- | (state ? ViewNode.FLAGS_FOCUSED : 0);
- }
-
- @Override
- public void setAccessibilityFocused(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED)
- | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0);
- }
-
- @Override
- public void setCheckable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE)
- | (state ? ViewNode.FLAGS_CHECKABLE : 0);
- }
-
- @Override
- public void setChecked(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED)
- | (state ? ViewNode.FLAGS_CHECKED : 0);
- }
-
- @Override
- public void setSelected(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED)
- | (state ? ViewNode.FLAGS_SELECTED : 0);
- }
-
- @Override
- public void setActivated(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED)
- | (state ? ViewNode.FLAGS_ACTIVATED : 0);
- }
-
- @Override
- public void setClassName(String className) {
- mNode.mClassName = className;
- }
-
- @Override
- public void setContentDescription(CharSequence contentDescription) {
- mNode.mContentDescription = contentDescription;
- }
-
- private final ViewNodeText getNodeText() {
- if (mNode.mText != null) {
- return mNode.mText;
- }
- mNode.mText = new ViewNodeText();
- return mNode.mText;
- }
-
- @Override
- public void setText(CharSequence text) {
- ViewNodeText t = getNodeText();
- t.mText = text;
- t.mTextSelectionStart = t.mTextSelectionEnd = -1;
- }
-
- @Override
- public void setText(CharSequence text, int selectionStart, int selectionEnd) {
- ViewNodeText t = getNodeText();
- t.mText = text;
- t.mTextSelectionStart = selectionStart;
- t.mTextSelectionEnd = selectionEnd;
- }
-
- @Override
- public void setTextStyle(float size, int fgColor, int bgColor, int style) {
- ViewNodeText t = getNodeText();
- t.mTextColor = fgColor;
- t.mTextBackgroundColor = bgColor;
- t.mTextSize = size;
- t.mTextStyle = style;
- }
-
- @Override
- public void setHint(CharSequence hint) {
- getNodeText().mHint = hint != null ? hint.toString() : null;
- }
-
- @Override
- public CharSequence getText() {
- return mNode.mText != null ? mNode.mText.mText : null;
- }
-
- @Override
- public int getTextSelectionStart() {
- return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1;
- }
-
- @Override
- public int getTextSelectionEnd() {
- return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1;
- }
-
- @Override
- public CharSequence getHint() {
- return mNode.mText != null ? mNode.mText.mHint : null;
- }
-
- @Override
- public Bundle getExtras() {
- if (mNode.mExtras != null) {
- return mNode.mExtras;
- }
- mNode.mExtras = new Bundle();
- return mNode.mExtras;
- }
-
- @Override
- public boolean hasExtras() {
- return mNode.mExtras != null;
- }
-
- @Override
- public void setChildCount(int num) {
- mNode.mChildren = new ViewNode[num];
- }
-
- @Override
- public int addChildCount(int num) {
- if (mNode.mChildren == null) {
- setChildCount(num);
- return 0;
- }
- final int start = mNode.mChildren.length;
- ViewNode[] newArray = new ViewNode[start + num];
- System.arraycopy(mNode.mChildren, 0, newArray, 0, start);
- mNode.mChildren = newArray;
- return start;
- }
-
- @Override
- public int getChildCount() {
- return mNode.mChildren != null ? mNode.mChildren.length : 0;
- }
-
- @Override
- public ViewAssistStructure newChild(int index) {
- ViewNode node = new ViewNode();
- mNode.mChildren[index] = node;
- return new ViewNodeBuilder(mAssist, node, false);
- }
-
- @Override
- public ViewAssistStructure asyncNewChild(int index) {
- synchronized (mAssist) {
- ViewNode node = new ViewNode();
- mNode.mChildren[index] = node;
- ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
- mAssist.mPendingAsyncChildren.add(builder);
- return builder;
- }
- }
-
- @Override
- public void asyncCommit() {
- synchronized (mAssist) {
- if (!mAsync) {
- throw new IllegalStateException("Child " + this
- + " was not created with ViewAssistStructure.asyncNewChild");
- }
- if (!mAssist.mPendingAsyncChildren.remove(this)) {
- throw new IllegalStateException("Child " + this + " already committed");
- }
- mAssist.notifyAll();
- }
- }
-
- @Override
- public Rect getTempRect() {
- return mAssist.mTmpRect;
- }
- }
-
- /** @hide */
- public AssistStructure(Activity activity) {
- mHaveData = true;
- mActivityComponent = activity.getComponentName();
- ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
- activity.getActivityToken());
- for (int i=0; i<views.size(); i++) {
- ViewRootImpl root = views.get(i);
- mWindowNodes.add(new WindowNode(this, root));
- }
- }
-
- public AssistStructure() {
- mHaveData = true;
- mActivityComponent = null;
- }
-
- /** @hide */
- public AssistStructure(Parcel in) {
- mReceiveChannel = in.readStrongBinder();
- }
-
- /** @hide */
- public void dump() {
- Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
- final int N = getWindowNodeCount();
- for (int i=0; i<N; i++) {
- WindowNode node = getWindowNodeAt(i);
- Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop()
- + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle());
- dump(" ", node.getRootViewNode());
- }
- }
-
- void dump(String prefix, ViewNode node) {
- Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
- + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
- int id = node.getId();
- if (id != 0) {
- StringBuilder sb = new StringBuilder();
- sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id));
- String entry = node.getIdEntry();
- if (entry != null) {
- String type = node.getIdType();
- String pkg = node.getIdPackage();
- sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type);
- sb.append("/"); sb.append(entry);
- }
- Log.i(TAG, sb.toString());
- }
- int scrollX = node.getScrollX();
- int scrollY = node.getScrollY();
- if (scrollX != 0 || scrollY != 0) {
- Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
- }
- CharSequence contentDescription = node.getContentDescription();
- if (contentDescription != null) {
- Log.i(TAG, prefix + " Content description: " + contentDescription);
- }
- CharSequence text = node.getText();
- if (text != null) {
- Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
- + node.getTextSelectionEnd() + "): " + text);
- Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
- + node.getTextStyle());
- Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
- + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
- }
- String hint = node.getHint();
- if (hint != null) {
- Log.i(TAG, prefix + " Hint: " + hint);
- }
- Bundle extras = node.getExtras();
- if (extras != null) {
- Log.i(TAG, prefix + " Extras: " + extras);
- }
- final int NCHILDREN = node.getChildCount();
- if (NCHILDREN > 0) {
- Log.i(TAG, prefix + " Children:");
- String cprefix = prefix + " ";
- for (int i=0; i<NCHILDREN; i++) {
- ViewNode cnode = node.getChildAt(i);
- dump(cprefix, cnode);
- }
- }
- }
-
- /**
- * @hide
- * Retrieve the framework-generated AssistStructure that is stored within
- * the Bundle filled in by {@link Activity#onProvideAssistData}.
- */
- public static android.app.assist.AssistStructure getAssistStructure(Bundle assistBundle) {
- return assistBundle.getParcelable(ASSIST_KEY);
- }
-
- /**
- * Return the activity this AssistStructure came from.
- */
- public ComponentName getActivityComponent() {
- ensureData();
- return mActivityComponent;
- }
-
- /**
- * Return the number of window contents that have been collected in this assist data.
- */
- public int getWindowNodeCount() {
- ensureData();
- return mWindowNodes.size();
- }
-
- /**
- * Return one of the windows in the assist data.
- * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1.
- * @hide
- */
- public WindowNode getWindowNodeAt(int index) {
- ensureData();
- return mWindowNodes.get(index);
- }
-
- /** @hide */
- public void ensureData() {
- if (mHaveData) {
- return;
- }
- mHaveData = true;
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(DESCRIPTOR);
- try {
- mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0);
- } catch (RemoteException e) {
- Log.w(TAG, "Failure reading AssistStructure data", e);
- return;
- }
- readContentFromParcel(reply);
- data.recycle();
- reply.recycle();
- }
-
- void writeContentToParcel(Parcel out, int flags) {
- // First make sure all content has been created.
- boolean skipStructure = false;
- synchronized (this) {
- long endTime = SystemClock.uptimeMillis() + 5000;
- long now;
- while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) {
- try {
- wait(endTime-now);
- } catch (InterruptedException e) {
- }
- }
- if (mPendingAsyncChildren.size() > 0) {
- // We waited too long, assume none of the assist structure is valid.
- skipStructure = true;
- }
- }
- int start = out.dataPosition();
- PooledStringWriter pwriter = new PooledStringWriter(out);
- ComponentName.writeToParcel(mActivityComponent, out);
- final int N = skipStructure ? 0 : mWindowNodes.size();
- out.writeInt(N);
- for (int i=0; i<N; i++) {
- mWindowNodes.get(i).writeToParcel(out, pwriter);
- }
- pwriter.finish();
- Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
- }
-
- void readContentFromParcel(Parcel in) {
- PooledStringReader preader = new PooledStringReader(in);
- mActivityComponent = ComponentName.readFromParcel(in);
- final int N = in.readInt();
- for (int i=0; i<N; i++) {
- mWindowNodes.add(new WindowNode(in, preader));
- }
- //dump();
- }
-}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5a0d246..af9decc 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3586,12 +3586,19 @@
* object.
*/
public Notification build() {
+ if (mSmallIcon != null) {
+ mSmallIcon.convertToAshmem();
+ }
+ if (mLargeIcon != null) {
+ mLargeIcon.convertToAshmem();
+ }
mOriginatingUserId = mContext.getUserId();
mHasThreeLines = hasThreeLines();
Notification n = buildUnstyled();
if (mStyle != null) {
+ mStyle.purgeResources();
n = mStyle.buildStyled(n);
}
@@ -3790,6 +3797,8 @@
return wip;
}
+ public void purgeResources() {}
+
// The following methods are split out so we can re-create notification partially.
/**
* @hide
@@ -3901,8 +3910,18 @@
return this;
}
- private RemoteViews makeBigContentView() {
+ @Override
+ public void purgeResources() {
+ super.purgeResources();
+ if (mPicture != null && mPicture.isMutable()) {
+ mPicture = mPicture.createAshmemBitmap();
+ }
+ if (mBigLargeIcon != null) {
+ mBigLargeIcon.convertToAshmem();
+ }
+ }
+ private RemoteViews makeBigContentView() {
// Replace mLargeIcon with mBigLargeIcon if mBigLargeIconSet
// This covers the following cases:
// 1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 9cc399d..abb8244 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -225,6 +225,9 @@
* Cancel this active request.
*/
public void cancel() {
+ if (mRequestInterface == null) {
+ throw new IllegalStateException("Request " + this + " is no longer active");
+ }
try {
mRequestInterface.cancel();
} catch (RemoteException e) {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 87e2f9a..a1bb40c 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -19,6 +19,7 @@
import android.accounts.AccountManager;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -227,14 +228,15 @@
"android.app.action.PROFILE_PROVISIONING_COMPLETE";
/**
+ * @hide
* Broadcast Action: This broadcast is sent to indicate that the system is ready for the device
* initializer to perform user setup tasks. This is only applicable to devices managed by a
* device owner app.
*
* <p>The broadcast will be limited to the {@link DeviceAdminReceiver} component specified in
- * the {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME} field
- * of the original intent or NFC bump that started the provisioning process. You will generally
- * handle this in {@link DeviceAdminReceiver#onReadyForUserInitialization}.
+ * the device initializer field of the original intent or NFC bump that started the provisioning
+ * process. You will generally handle this in
+ * {@link DeviceAdminReceiver#onReadyForUserInitialization}.
*
* <p>Input: Nothing.</p>
* <p>Output: Nothing</p>
@@ -435,23 +437,22 @@
* Called during provisioning of a managed device to allow the device initializer to perform
* user setup steps. Only device initializers should override this method.
*
- * <p> Called when the DeviceAdminReceiver receives a
- * {@link #ACTION_READY_FOR_USER_INITIALIZATION} broadcast. As a prerequisite for the execution
- * of this callback the {@link DeviceAdminReceiver} has
- * to declare an intent filter for {@link #ACTION_READY_FOR_USER_INITIALIZATION}. Only the
- * component specified in the
- * {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME} field of the
+ * <p> Called when the DeviceAdminReceiver receives an
+ * android.app.action.ACTION_READY_FOR_USER_INITIALIZATION broadcast. As a prerequisite for the
+ * execution of this callback the {@link DeviceAdminReceiver} has
+ * to declare an intent filter for android.app.action.ACTION_READY_FOR_USER_INITIALIZATION. Only
+ * the component specified in the device initializer component name field of the
* original intent or NFC bump that started the provisioning process will receive this callback.
*
* <p>It is not assumed that the device initializer is finished when it returns from
- * this call, as it may do additional setup asynchronously. The device initializer must call
- * {@link DevicePolicyManager#setUserEnabled(ComponentName admin)} when it has finished any
- * additional setup (such as adding an account by using the {@link AccountManager}) in order for
- * the user to be functional.
+ * this call, as it may do additional setup asynchronously. The device initializer must enable
+ * the current user when it has finished any additional setup (such as adding an account by
+ * using the {@link AccountManager}) in order for the user to be functional.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
+ @SystemApi
public void onReadyForUserInitialization(Context context, Intent intent) {
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b9862ca..4d1cff5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -468,6 +468,7 @@
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
/**
+ * @hide
* On devices managed by a device owner app, a {@link ComponentName} extra indicating the
* component of the application that is temporarily granted device owner privileges during
* device initialization and profile owner privileges during secondary user initialization.
@@ -483,6 +484,7 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
/**
+ * @hide
* A String extra holding an http url that specifies the download location of the device
* initializer package. When not provided it is assumed that the device initializer package is
* already installed.
@@ -494,6 +496,7 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
/**
+ * @hide
* An int extra holding a minimum required version code for the device initializer package.
* If the initializer is already installed on the device, it will only be re-downloaded from
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION} if the version of
@@ -506,6 +509,7 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
/**
+ * @hide
* A String extra holding a http cookie header which should be used in the http request to the
* url specified in {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -516,6 +520,7 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
+ * @hide
* A String extra holding the URL-safe base64 encoded SHA-256 checksum of the file at download
* location specified in
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
@@ -532,6 +537,7 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
/**
+ * @hide
* A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
@@ -611,11 +617,6 @@
* {@link #MIME_TYPE_PROVISIONING_NFC}:
* <ul>
* <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}.
* Replaces {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}. The value of the property
* should be converted to a String via
@@ -2756,6 +2757,7 @@
}
/**
+ * @hide
* Sets the given component as the device initializer. The package must already be installed and
* set as an active device administrator, and there must not be an existing device initializer,
* for this call to succeed. This method can only be called by an app holding the
@@ -2784,6 +2786,7 @@
}
/**
+ * @hide
* Used to determine if a particular package has been registered as the device initializer.
*
* @param packageName the package name of the app, to compare with the registered device
@@ -2802,6 +2805,7 @@
}
/**
+ * @hide
* Removes the device initializer, so that it will not be invoked on user initialization for any
* subsequently created users. This method can be called by either the device owner or device
* initializer itself. The caller must be an active administrator.
@@ -2856,6 +2860,7 @@
/**
+ * @hide
* Sets the enabled state of the user. A user should be enabled only once it is ready to
* be used.
*
@@ -3967,6 +3972,7 @@
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
* This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
* and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
+ * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
* </ul>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -4344,6 +4350,12 @@
* group that the runtime permission belongs to. This method can only be called
* by a profile or device owner.
*
+ * <p/>Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not
+ * revoke the permission. It retains the previous grant, if any.
+ *
+ * <p/>Permissions can be granted or revoked only for applications built with a
+ * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ *
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
* @param permission The permission to grant or revoke.
diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java
index c7e7330..07b2d57 100644
--- a/core/java/android/app/assist/AssistContent.java
+++ b/core/java/android/app/assist/AssistContent.java
@@ -1,24 +1,184 @@
package android.app.assist;
+import android.content.ClipData;
import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * New home for AssistContent.
+ * Holds information about the content an application is viewing, to hand to an
+ * assistant at the user's request. This is filled in by
+ * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
*/
-public final class AssistContent extends android.app.AssistContent implements Parcelable {
+@Deprecated
+public class AssistContent implements Parcelable {
+ private boolean mIsAppProvidedIntent = false;
+ private Intent mIntent;
+ private String mStructuredData;
+ private ClipData mClipData;
+ private Uri mUri;
+ private final Bundle mExtras;
- /** @hide */
public AssistContent() {
+ mExtras = new Bundle();
}
- public AssistContent(Parcel in) {
- super(in);
+ /**
+ * @hide
+ * Called by {@link android.app.ActivityThread} to set the default Intent based on
+ * {@link android.app.Activity#getIntent Activity.getIntent}.
+ *
+ * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
+ * of a web (http or https scheme) URI.</p>
+ */
+ public void setDefaultIntent(Intent intent) {
+ mIntent = intent;
+ setWebUri(null);
+ if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ if (uri != null) {
+ if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
+ setWebUri(uri);
+ }
+ }
+ }
}
+ /**
+ * Sets the Intent associated with the content, describing the current top-level context of
+ * the activity. If this contains a reference to a piece of data related to the activity,
+ * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
+ * service can access it.
+ */
+ public void setIntent(Intent intent) {
+ mIsAppProvidedIntent = true;
+ mIntent = intent;
+ }
+
+ /**
+ * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
+ * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
+ */
public Intent getIntent() {
- return super.getIntent();
+ return mIntent;
+ }
+
+ /**
+ * Returns whether or not the current Intent was explicitly provided in
+ * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
+ * the Intent was automatically set based on
+ * {@link android.app.Activity#getIntent Activity.getIntent}.
+ */
+ public boolean isAppProvidedIntent() {
+ return mIsAppProvidedIntent;
+ }
+
+ /**
+ * Optional additional content items that are involved with
+ * the current UI. Access to this content will be granted to the assistant as if you
+ * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+ */
+ public void setClipData(ClipData clip) {
+ mClipData = clip;
+ }
+
+ /**
+ * Return the current {@link #setClipData}, which you can modify in-place.
+ */
+ public ClipData getClipData() {
+ return mClipData;
+ }
+
+ /**
+ * Sets optional structured data regarding the content being viewed. The provided data
+ * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
+ * <a href="http://schema.org/">schema.org</a> vocabulary.
+ */
+ public void setStructuredData(String structuredData) {
+ mStructuredData = structuredData;
+ }
+
+ /**
+ * Returns the current {@link #setStructuredData}.
+ */
+ public String getStructuredData() {
+ return mStructuredData;
+ }
+
+ /**
+ * Set a web URI associated with the current data being shown to the user.
+ * This URI could be opened in a web browser, or in the app as an
+ * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
+ * being displayed by it. The URI here should be something that is transportable
+ * off the device into other environments to acesss the same data as is currently
+ * being shown in the app; if the app does not have such a representation, it should
+ * leave the null and only report the local intent and clip data.
+ */
+ public void setWebUri(Uri uri) {
+ mUri = uri;
+ }
+
+ /**
+ * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
+ * there is none.
+ */
+ public Uri getWebUri() {
+ return mUri;
+ }
+
+ /**
+ * Return Bundle for extra vendor-specific data that can be modified and examined.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ AssistContent(Parcel in) {
+ if (in.readInt() != 0) {
+ mIntent = Intent.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mClipData = ClipData.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mUri = Uri.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mStructuredData = in.readString();
+ }
+ mIsAppProvidedIntent = in.readInt() == 1;
+ mExtras = in.readBundle();
+ }
+
+ void writeToParcelInternal(Parcel dest, int flags) {
+ if (mIntent != null) {
+ dest.writeInt(1);
+ mIntent.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mClipData != null) {
+ dest.writeInt(1);
+ mClipData.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mUri != null) {
+ dest.writeInt(1);
+ mUri.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mStructuredData != null) {
+ dest.writeInt(1);
+ dest.writeString(mStructuredData);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
+ dest.writeBundle(mExtras);
}
@Override
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 1677e95..284dfd6 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1,28 +1,1038 @@
package android.app.assist;
import android.app.Activity;
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PooledStringReader;
+import android.os.PooledStringWriter;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewStructure;
+import android.view.ViewRootImpl;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import java.util.ArrayList;
/**
- * New home for AssistStructure.
+ * Assist data automatically created by the platform's implementation
+ * of {@link android.app.Activity#onProvideAssistData}.
*/
-public final class AssistStructure extends android.app.AssistStructure implements Parcelable {
+public class AssistStructure implements Parcelable {
+ static final String TAG = "AssistStructure";
- public AssistStructure() {
+ boolean mHaveData;
+
+ ComponentName mActivityComponent;
+
+ final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
+
+ final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
+
+ SendChannel mSendChannel;
+ IBinder mReceiveChannel;
+
+ Rect mTmpRect = new Rect();
+
+ static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
+ static final String DESCRIPTOR = "android.app.AssistStructure";
+
+ final class SendChannel extends Binder {
+ @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ if (code == TRANSACTION_XFER) {
+ data.enforceInterface(DESCRIPTOR);
+ writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ return true;
+ } else {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+ }
+
+ final static class ViewNodeText {
+ CharSequence mText;
+ int mTextSelectionStart;
+ int mTextSelectionEnd;
+ int mTextColor;
+ int mTextBackgroundColor;
+ float mTextSize;
+ int mTextStyle;
+ String mHint;
+
+ ViewNodeText() {
+ }
+
+ ViewNodeText(Parcel in) {
+ mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mTextSelectionStart = in.readInt();
+ mTextSelectionEnd = in.readInt();
+ mTextColor = in.readInt();
+ mTextBackgroundColor = in.readInt();
+ mTextSize = in.readFloat();
+ mTextStyle = in.readInt();
+ mHint = in.readString();
+ }
+
+ void writeToParcel(Parcel out) {
+ TextUtils.writeToParcel(mText, out, 0);
+ out.writeInt(mTextSelectionStart);
+ out.writeInt(mTextSelectionEnd);
+ out.writeInt(mTextColor);
+ out.writeInt(mTextBackgroundColor);
+ out.writeFloat(mTextSize);
+ out.writeInt(mTextStyle);
+ out.writeString(mHint);
+ }
+ }
+
+ /**
+ * Describes a window in the assist data.
+ */
+ static public class WindowNode {
+ final int mX;
+ final int mY;
+ final int mWidth;
+ final int mHeight;
+ final CharSequence mTitle;
+ final int mDisplayId;
+ final ViewNode mRoot;
+
+ WindowNode(AssistStructure assist, ViewRootImpl root) {
+ View view = root.getView();
+ Rect rect = new Rect();
+ view.getBoundsOnScreen(rect);
+ mX = rect.left - view.getLeft();
+ mY = rect.top - view.getTop();
+ mWidth = rect.width();
+ mHeight = rect.height();
+ mTitle = root.getTitle();
+ mDisplayId = root.getDisplayId();
+ mRoot = new ViewNode();
+ ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
+ if ((root.getWindowFlags()& WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ // This is a secure window, so it doesn't want a screenshot, and that
+ // means we should also not copy out its view hierarchy.
+ view.onProvideStructure(builder);
+ builder.setAssistBlocked(true);
+ return;
+ }
+ view.dispatchProvideStructure(builder);
+ }
+
+ WindowNode(Parcel in, PooledStringReader preader) {
+ mX = in.readInt();
+ mY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mDisplayId = in.readInt();
+ mRoot = new ViewNode(in, preader);
+ }
+
+ void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ TextUtils.writeToParcel(mTitle, out, 0);
+ out.writeInt(mDisplayId);
+ mRoot.writeToParcel(out, pwriter);
+ }
+
+ /**
+ * Returns the left edge of the window, in pixels, relative to the left
+ * edge of the screen.
+ */
+ public int getLeft() {
+ return mX;
+ }
+
+ /**
+ * Returns the top edge of the window, in pixels, relative to the top
+ * edge of the screen.
+ */
+ public int getTop() {
+ return mY;
+ }
+
+ /**
+ * Returns the total width of the window in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the total height of the window in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the title associated with the window, if it has one.
+ */
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns the ID of the display this window is on, for use with
+ * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Returns the {@link ViewNode} containing the root content of the window.
+ */
+ public ViewNode getRootViewNode() {
+ return mRoot;
+ }
+ }
+
+ /**
+ * Describes a single view in the assist data.
+ */
+ static public class ViewNode {
+ /**
+ * Magic value for text color that has not been defined, which is very unlikely
+ * to be confused with a real text color.
+ */
+ public static final int TEXT_COLOR_UNDEFINED = 1;
+
+ public static final int TEXT_STYLE_BOLD = 1<<0;
+ public static final int TEXT_STYLE_ITALIC = 1<<1;
+ public static final int TEXT_STYLE_UNDERLINE = 1<<2;
+ public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
+
+ int mId;
+ String mIdPackage;
+ String mIdType;
+ String mIdEntry;
+ int mX;
+ int mY;
+ int mScrollX;
+ int mScrollY;
+ int mWidth;
+ int mHeight;
+
+ static final int FLAGS_DISABLED = 0x00000001;
+ static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
+ static final int FLAGS_FOCUSABLE = 0x00000010;
+ static final int FLAGS_FOCUSED = 0x00000020;
+ static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
+ static final int FLAGS_SELECTED = 0x00000040;
+ static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
+ static final int FLAGS_ACTIVATED = 0x40000000;
+ static final int FLAGS_CHECKABLE = 0x00000100;
+ static final int FLAGS_CHECKED = 0x00000200;
+ static final int FLAGS_CLICKABLE = 0x00004000;
+ static final int FLAGS_LONG_CLICKABLE = 0x00200000;
+ static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
+
+ int mFlags;
+
+ String mClassName;
+ CharSequence mContentDescription;
+
+ ViewNodeText mText;
+ Bundle mExtras;
+
+ ViewNode[] mChildren;
+
+ ViewNode() {
+ }
+
+ ViewNode(Parcel in, PooledStringReader preader) {
+ mId = in.readInt();
+ if (mId != 0) {
+ mIdEntry = preader.readString();
+ if (mIdEntry != null) {
+ mIdType = preader.readString();
+ mIdPackage = preader.readString();
+ } else {
+ mIdPackage = mIdType = null;
+ }
+ } else {
+ mIdPackage = mIdType = mIdEntry = null;
+ }
+ mX = in.readInt();
+ mY = in.readInt();
+ mScrollX = in.readInt();
+ mScrollY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ mFlags = in.readInt();
+ mClassName = preader.readString();
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ if (in.readInt() != 0) {
+ mText = new ViewNodeText(in);
+ } else {
+ mText = null;
+ }
+ mExtras = in.readBundle();
+ final int NCHILDREN = in.readInt();
+ if (NCHILDREN > 0) {
+ mChildren = new ViewNode[NCHILDREN];
+ for (int i=0; i<NCHILDREN; i++) {
+ mChildren[i] = new ViewNode(in, preader);
+ }
+ } else {
+ mChildren = null;
+ }
+ }
+
+ void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ out.writeInt(mId);
+ if (mId != 0) {
+ pwriter.writeString(mIdEntry);
+ if (mIdEntry != null) {
+ pwriter.writeString(mIdType);
+ pwriter.writeString(mIdPackage);
+ }
+ }
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mScrollX);
+ out.writeInt(mScrollY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ out.writeInt(mFlags);
+ pwriter.writeString(mClassName);
+ TextUtils.writeToParcel(mContentDescription, out, 0);
+ if (mText != null) {
+ out.writeInt(1);
+ mText.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
+ out.writeBundle(mExtras);
+ if (mChildren != null) {
+ final int NCHILDREN = mChildren.length;
+ out.writeInt(NCHILDREN);
+ for (int i=0; i<NCHILDREN; i++) {
+ mChildren[i].writeToParcel(out, pwriter);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ /**
+ * Returns the ID associated with this view, as per {@link View#getId() View.getId()}.
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the package name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdPackage() {
+ return mIdPackage;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the type name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdType() {
+ return mIdType;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the entry name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdEntry() {
+ return mIdEntry;
+ }
+
+ /**
+ * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
+ */
+ public int getLeft() {
+ return mX;
+ }
+
+ /**
+ * Returns the top edge of this view, in pixels, relative to the top edge of its parent.
+ */
+ public int getTop() {
+ return mY;
+ }
+
+ /**
+ * Returns the current X scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollX()}.
+ */
+ public int getScrollX() {
+ return mScrollX;
+ }
+
+ /**
+ * Returns the current Y scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollY()}.
+ */
+ public int getScrollY() {
+ return mScrollY;
+ }
+
+ /**
+ * Returns the width of this view, in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the height of this view, in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the visibility mode of this view, as per
+ * {@link android.view.View#getVisibility() View.getVisibility()}.
+ */
+ public int getVisibility() {
+ return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
+ }
+
+ /**
+ * Returns true if assist data has been blocked starting at this node in the hierarchy.
+ */
+ public boolean isAssistBlocked() {
+ return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
+ }
+
+ /**
+ * Returns true if this node is in an enabled state.
+ */
+ public boolean isEnabled() {
+ return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
+ }
+
+ /**
+ * Returns true if this node is clickable by the user.
+ */
+ public boolean isClickable() {
+ return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node can take input focus.
+ */
+ public boolean isFocusable() {
+ return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node currently had input focus at the time that the
+ * structure was collected.
+ */
+ public boolean isFocused() {
+ return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
+ }
+
+ /**
+ * Returns true if this node currently had accessibility focus at the time that the
+ * structure was collected.
+ */
+ public boolean isAccessibilityFocused() {
+ return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
+ }
+
+ /**
+ * Returns true if this node represents something that is checkable by the user.
+ */
+ public boolean isCheckable() {
+ return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node is currently in a checked state.
+ */
+ public boolean isChecked() {
+ return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
+ }
+
+ /**
+ * Returns true if this node has currently been selected by the user.
+ */
+ public boolean isSelected() {
+ return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
+ }
+
+ /**
+ * Returns true if this node has currently been activated by the user.
+ */
+ public boolean isActivated() {
+ return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
+ }
+
+ /**
+ * Returns true if this node is something the user can perform a long click/press on.
+ */
+ public boolean isLongClickable() {
+ return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node is something the user can perform a context click on.
+ */
+ public boolean isContextClickable() {
+ return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns the class name of the node's implementation, indicating its behavior.
+ * For example, a button will report "android.widget.Button" meaning it behaves
+ * like a {@link android.widget.Button}.
+ */
+ public String getClassName() {
+ return mClassName;
+ }
+
+ /**
+ * Returns any content description associated with the node, which semantically describes
+ * its purpose for accessibility and other uses.
+ */
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Returns any text associated with the node that is displayed to the user, or null
+ * if there is none.
+ */
+ public CharSequence getText() {
+ return mText != null ? mText.mText : null;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ */
+ public int getTextSelectionStart() {
+ return mText != null ? mText.mTextSelectionStart : -1;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
+ * indicating the cursor position.
+ */
+ public int getTextSelectionEnd() {
+ return mText != null ? mText.mTextSelectionEnd : -1;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text color associated with it.
+ * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
+ public int getTextColor() {
+ return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text background color associated
+ * with it.
+ * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
+ public int getTextBackgroundColor() {
+ return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text size (in pixels) associated
+ * with it.
+ * Note that the text may also contain style spans that modify the size of specific
+ * parts of the text.
+ */
+ public float getTextSize() {
+ return mText != null ? mText.mTextSize : 0;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text style associated
+ * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD},
+ * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or
+ * {@link #TEXT_STYLE_UNDERLINE}.
+ * Note that the text may also contain style spans that modify the style of specific
+ * parts of the text.
+ */
+ public int getTextStyle() {
+ return mText != null ? mText.mTextStyle : 0;
+ }
+
+ /**
+ * Return additional hint text associated with the node; this is typically used with
+ * a node that takes user input, describing to the user what the input means.
+ */
+ public String getHint() {
+ return mText != null ? mText.mHint : null;
+ }
+
+ /**
+ * Return a Bundle containing optional vendor-specific extension information.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Return the number of children this node has.
+ */
+ public int getChildCount() {
+ return mChildren != null ? mChildren.length : 0;
+ }
+
+ /**
+ * Return a child of this node, given an index value from 0 to
+ * {@link #getChildCount()}-1.
+ */
+ public ViewNode getChildAt(int index) {
+ return mChildren[index];
+ }
+ }
+
+ static class ViewNodeBuilder extends ViewStructure {
+ final AssistStructure mAssist;
+ final ViewNode mNode;
+ final boolean mAsync;
+
+ ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) {
+ mAssist = assist;
+ mNode = node;
+ mAsync = async;
+ }
+
+ @Override
+ public void setId(int id, String packageName, String typeName, String entryName) {
+ mNode.mId = id;
+ mNode.mIdPackage = packageName;
+ mNode.mIdType = typeName;
+ mNode.mIdEntry = entryName;
+ }
+
+ @Override
+ public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
+ mNode.mX = left;
+ mNode.mY = top;
+ mNode.mScrollX = scrollX;
+ mNode.mScrollY = scrollY;
+ mNode.mWidth = width;
+ mNode.mHeight = height;
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
+ }
+
+ @Override
+ public void setAssistBlocked(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
+ | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
+ }
+
+ @Override
+ public void setEnabled(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED)
+ | (state ? 0 : ViewNode.FLAGS_DISABLED);
+ }
+
+ @Override
+ public void setClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE)
+ | (state ? ViewNode.FLAGS_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setLongClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE)
+ | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setContextClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE)
+ | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setFocusable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
+ | (state ? ViewNode.FLAGS_FOCUSABLE : 0);
+ }
+
+ @Override
+ public void setFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED)
+ | (state ? ViewNode.FLAGS_FOCUSED : 0);
+ }
+
+ @Override
+ public void setAccessibilityFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED)
+ | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0);
+ }
+
+ @Override
+ public void setCheckable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE)
+ | (state ? ViewNode.FLAGS_CHECKABLE : 0);
+ }
+
+ @Override
+ public void setChecked(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED)
+ | (state ? ViewNode.FLAGS_CHECKED : 0);
+ }
+
+ @Override
+ public void setSelected(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED)
+ | (state ? ViewNode.FLAGS_SELECTED : 0);
+ }
+
+ @Override
+ public void setActivated(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED)
+ | (state ? ViewNode.FLAGS_ACTIVATED : 0);
+ }
+
+ @Override
+ public void setClassName(String className) {
+ mNode.mClassName = className;
+ }
+
+ @Override
+ public void setContentDescription(CharSequence contentDescription) {
+ mNode.mContentDescription = contentDescription;
+ }
+
+ private final ViewNodeText getNodeText() {
+ if (mNode.mText != null) {
+ return mNode.mText;
+ }
+ mNode.mText = new ViewNodeText();
+ return mNode.mText;
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = t.mTextSelectionEnd = -1;
+ }
+
+ @Override
+ public void setText(CharSequence text, int selectionStart, int selectionEnd) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = selectionStart;
+ t.mTextSelectionEnd = selectionEnd;
+ }
+
+ @Override
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
+ ViewNodeText t = getNodeText();
+ t.mTextColor = fgColor;
+ t.mTextBackgroundColor = bgColor;
+ t.mTextSize = size;
+ t.mTextStyle = style;
+ }
+
+ @Override
+ public void setHint(CharSequence hint) {
+ getNodeText().mHint = hint != null ? hint.toString() : null;
+ }
+
+ @Override
+ public CharSequence getText() {
+ return mNode.mText != null ? mNode.mText.mText : null;
+ }
+
+ @Override
+ public int getTextSelectionStart() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1;
+ }
+
+ @Override
+ public int getTextSelectionEnd() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1;
+ }
+
+ @Override
+ public CharSequence getHint() {
+ return mNode.mText != null ? mNode.mText.mHint : null;
+ }
+
+ @Override
+ public Bundle getExtras() {
+ if (mNode.mExtras != null) {
+ return mNode.mExtras;
+ }
+ mNode.mExtras = new Bundle();
+ return mNode.mExtras;
+ }
+
+ @Override
+ public boolean hasExtras() {
+ return mNode.mExtras != null;
+ }
+
+ @Override
+ public void setChildCount(int num) {
+ mNode.mChildren = new ViewNode[num];
+ }
+
+ @Override
+ public int addChildCount(int num) {
+ if (mNode.mChildren == null) {
+ setChildCount(num);
+ return 0;
+ }
+ final int start = mNode.mChildren.length;
+ ViewNode[] newArray = new ViewNode[start + num];
+ System.arraycopy(mNode.mChildren, 0, newArray, 0, start);
+ mNode.mChildren = newArray;
+ return start;
+ }
+
+ @Override
+ public int getChildCount() {
+ return mNode.mChildren != null ? mNode.mChildren.length : 0;
+ }
+
+ @Override
+ public ViewStructure newChild(int index) {
+ ViewNode node = new ViewNode();
+ mNode.mChildren[index] = node;
+ return new ViewNodeBuilder(mAssist, node, false);
+ }
+
+ @Override
+ public ViewStructure asyncNewChild(int index) {
+ synchronized (mAssist) {
+ ViewNode node = new ViewNode();
+ mNode.mChildren[index] = node;
+ ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
+ mAssist.mPendingAsyncChildren.add(builder);
+ return builder;
+ }
+ }
+
+ @Override
+ public void asyncCommit() {
+ synchronized (mAssist) {
+ if (!mAsync) {
+ throw new IllegalStateException("Child " + this
+ + " was not created with ViewStructure.asyncNewChild");
+ }
+ if (!mAssist.mPendingAsyncChildren.remove(this)) {
+ throw new IllegalStateException("Child " + this + " already committed");
+ }
+ mAssist.notifyAll();
+ }
+ }
+
+ @Override
+ public Rect getTempRect() {
+ return mAssist.mTmpRect;
+ }
}
/** @hide */
public AssistStructure(Activity activity) {
- super(activity);
+ mHaveData = true;
+ mActivityComponent = activity.getComponentName();
+ ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
+ activity.getActivityToken());
+ for (int i=0; i<views.size(); i++) {
+ ViewRootImpl root = views.get(i);
+ mWindowNodes.add(new WindowNode(this, root));
+ }
}
- AssistStructure(Parcel in) {
- super(in);
+ public AssistStructure() {
+ mHaveData = true;
+ mActivityComponent = null;
}
+ /** @hide */
+ public AssistStructure(Parcel in) {
+ mReceiveChannel = in.readStrongBinder();
+ }
+
+ /** @hide */
+ public void dump() {
+ Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
+ final int N = getWindowNodeCount();
+ for (int i=0; i<N; i++) {
+ WindowNode node = getWindowNodeAt(i);
+ Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop()
+ + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle());
+ dump(" ", node.getRootViewNode());
+ }
+ }
+
+ void dump(String prefix, ViewNode node) {
+ Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
+ + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
+ int id = node.getId();
+ if (id != 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id));
+ String entry = node.getIdEntry();
+ if (entry != null) {
+ String type = node.getIdType();
+ String pkg = node.getIdPackage();
+ sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type);
+ sb.append("/"); sb.append(entry);
+ }
+ Log.i(TAG, sb.toString());
+ }
+ int scrollX = node.getScrollX();
+ int scrollY = node.getScrollY();
+ if (scrollX != 0 || scrollY != 0) {
+ Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
+ }
+ CharSequence contentDescription = node.getContentDescription();
+ if (contentDescription != null) {
+ Log.i(TAG, prefix + " Content description: " + contentDescription);
+ }
+ CharSequence text = node.getText();
+ if (text != null) {
+ Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
+ + node.getTextSelectionEnd() + "): " + text);
+ Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
+ + node.getTextStyle());
+ Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
+ + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
+ }
+ String hint = node.getHint();
+ if (hint != null) {
+ Log.i(TAG, prefix + " Hint: " + hint);
+ }
+ Bundle extras = node.getExtras();
+ if (extras != null) {
+ Log.i(TAG, prefix + " Extras: " + extras);
+ }
+ final int NCHILDREN = node.getChildCount();
+ if (NCHILDREN > 0) {
+ Log.i(TAG, prefix + " Children:");
+ String cprefix = prefix + " ";
+ for (int i=0; i<NCHILDREN; i++) {
+ ViewNode cnode = node.getChildAt(i);
+ dump(cprefix, cnode);
+ }
+ }
+ }
+
+ /**
+ * Return the activity this AssistStructure came from.
+ */
+ public ComponentName getActivityComponent() {
+ ensureData();
+ return mActivityComponent;
+ }
+
+ /**
+ * Return the number of window contents that have been collected in this assist data.
+ */
+ public int getWindowNodeCount() {
+ ensureData();
+ return mWindowNodes.size();
+ }
+
+ /**
+ * Return one of the windows in the assist data.
+ * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1.
+ */
public WindowNode getWindowNodeAt(int index) {
- return super.getWindowNodeAt(index);
+ ensureData();
+ return mWindowNodes.get(index);
+ }
+
+ /** @hide */
+ public void ensureData() {
+ if (mHaveData) {
+ return;
+ }
+ mHaveData = true;
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(DESCRIPTOR);
+ try {
+ mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failure reading AssistStructure data", e);
+ return;
+ }
+ readContentFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ }
+
+ void writeContentToParcel(Parcel out, int flags) {
+ // First make sure all content has been created.
+ boolean skipStructure = false;
+ synchronized (this) {
+ long endTime = SystemClock.uptimeMillis() + 5000;
+ long now;
+ while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) {
+ try {
+ wait(endTime-now);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (mPendingAsyncChildren.size() > 0) {
+ // We waited too long, assume none of the assist structure is valid.
+ skipStructure = true;
+ }
+ }
+ int start = out.dataPosition();
+ PooledStringWriter pwriter = new PooledStringWriter(out);
+ ComponentName.writeToParcel(mActivityComponent, out);
+ final int N = skipStructure ? 0 : mWindowNodes.size();
+ out.writeInt(N);
+ for (int i=0; i<N; i++) {
+ mWindowNodes.get(i).writeToParcel(out, pwriter);
+ }
+ pwriter.finish();
+ Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
+ }
+
+ void readContentFromParcel(Parcel in) {
+ PooledStringReader preader = new PooledStringReader(in);
+ mActivityComponent = ComponentName.readFromParcel(in);
+ final int N = in.readInt();
+ for (int i=0; i<N; i++) {
+ mWindowNodes.add(new WindowNode(in, preader));
+ }
+ //dump();
}
public int describeContents() {
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 8a31390..9113426 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -77,6 +77,12 @@
public abstract boolean isAppIdle(String packageName, int userId);
/**
+ * @return True if currently app idle parole mode is on. This means all idle apps are allow to
+ * run for a short period of time.
+ */
+ public abstract boolean isAppIdleParoleOn();
+
+ /**
* Sets up a listener for changes to packages being accessed.
* @param listener A listener within the system process.
*/
@@ -90,8 +96,9 @@
public abstract void removeAppIdleStateChangeListener(
AppIdleStateChangeListener listener);
- public interface AppIdleStateChangeListener {
- void onAppIdleStateChanged(String packageName, int userId, boolean idle);
+ public static abstract class AppIdleStateChangeListener {
+ public abstract void onAppIdleStateChanged(String packageName, int userId, boolean idle);
+ public abstract void onParoleStateChanged(boolean isParoleOn);
}
}
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 809f900..58bd5cd 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -28,13 +28,26 @@
/**
* An abstract implementation of a SyncAdapter that spawns a thread to invoke a sync operation.
- * If a sync operation is already in progress when a startSync() request is received then an error
- * will be returned to the new request and the existing request will be allowed to continue.
- * When a startSync() is received and there is no sync operation in progress then a thread
- * will be started to run the operation and {@link #onPerformSync} will be invoked on that thread.
- * If a cancelSync() is received that matches an existing sync operation then the thread
- * that is running that sync operation will be interrupted, which will indicate to the thread
- * that the sync has been canceled.
+ * If a sync operation is already in progress when a sync request is received, an error will be
+ * returned to the new request and the existing request will be allowed to continue.
+ * However if there is no sync in progress then a thread will be spawned and {@link #onPerformSync}
+ * will be invoked on that thread.
+ * <p>
+ * Syncs can be cancelled at any time by the framework. For example a sync that was not
+ * user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled.
+ * Similarly the framework will attempt to determine whether or not an adapter is making progress
+ * by monitoring its network activity over the course of a minute. If the network traffic over this
+ * window is close enough to zero the sync will be cancelled. You can also request the sync be
+ * cancelled via {@link ContentResolver#cancelSync(Account, String)} or
+ * {@link ContentResolver#cancelSync(SyncRequest)}.
+ * <p>
+ * A sync is cancelled by issuing a {@link Thread#interrupt()} on the syncing thread. <strong>Either
+ * your code in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}
+ * must check {@link Thread#interrupted()}, or you you must override one of
+ * {@link #onSyncCanceled(Thread)}/{@link #onSyncCanceled()}</strong> (depending on whether or not
+ * your adapter supports syncing of multiple accounts in parallel). If your adapter does not
+ * respect the cancel issued by the framework you run the risk of your app's entire process being
+ * killed.
* <p>
* In order to be a sync adapter one must extend this class, provide implementations for the
* abstract methods and write a service that returns the result of {@link #getSyncAdapterBinder()}
@@ -261,6 +274,10 @@
} else {
syncResult.databaseError = true;
}
+ } catch (SecurityException e) {
+ AbstractThreadedSyncAdapter.this.onSecurityException(mAccount, mExtras,
+ mAuthority, syncResult);
+ syncResult.databaseError = true;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
@@ -306,6 +323,20 @@
String authority, ContentProviderClient provider, SyncResult syncResult);
/**
+ * Report that there was a security exception when opening the content provider
+ * prior to calling {@link #onPerformSync}. This will be treated as a sync
+ * database failure.
+ *
+ * @param account the account that attempted to sync
+ * @param extras SyncAdapter-specific parameters
+ * @param authority the authority of the failed sync request
+ * @param syncResult SyncAdapter-specific parameters
+ */
+ public void onSecurityException(Account account, Bundle extras,
+ String authority, SyncResult syncResult) {
+ }
+
+ /**
* Indicates that a sync operation has been canceled. This will be invoked on a separate
* thread than the sync thread and so you must consider the multi-threaded implications
* of the work that you do in this method.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0c07bc3..cb68d74 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -31,6 +31,7 @@
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.IPackagesProvider;
import android.content.pm.IOnPermissionsChangeListener;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.InstrumentationInfo;
@@ -106,6 +107,8 @@
void updatePermissionFlags(String permissionName, String packageName, int flagMask,
int flagValues, int userId);
+ void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
+
boolean shouldShowRequestPermissionRationale(String permissionName,
String packageName, int userId);
@@ -282,6 +285,10 @@
*/
byte[] getPreferredActivityBackup(int userId);
void restorePreferredActivities(in byte[] backup, int userId);
+ byte[] getDefaultAppsBackup(int userId);
+ void restoreDefaultApps(in byte[] backup, int userId);
+ byte[] getIntentFilterVerificationBackup(int userId);
+ void restoreIntentFilterVerification(in byte[] backup, int userId);
/**
* Report the set of 'Home' activity candidates, plus (if any) which of them
@@ -299,18 +306,18 @@
* As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}.
*/
int getComponentEnabledSetting(in ComponentName componentName, int userId);
-
+
/**
* As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.
*/
void setApplicationEnabledSetting(in String packageName, in int newState, int flags,
int userId, String callingPackage);
-
+
/**
* As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}.
*/
int getApplicationEnabledSetting(in String packageName, int userId);
-
+
/**
* Set whether the given package should be considered stopped, making
* it not visible to implicit intents that filter out stopped packages.
@@ -363,7 +370,7 @@
*/
void freeStorage(in String volumeUuid, in long freeStorageSize,
in IntentSender pi);
-
+
/**
* Delete all the cache files in an applications cache directory
* @param packageName The package name of the application whose cache
@@ -371,7 +378,7 @@
* @param observer a callback used to notify when the deletion is finished.
*/
void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
-
+
/**
* Clear the user data directory of an application.
* @param packageName The package name of the application whose cache
@@ -379,7 +386,7 @@
* @param observer a callback used to notify when the operation is completed.
*/
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
-
+
/**
* Get package statistics including the code, data and cache size for
* an already installed package
@@ -389,7 +396,7 @@
* retrieval of information is complete.
*/
void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer);
-
+
/**
* Get a list of shared libraries that are available on the
* system.
@@ -403,7 +410,7 @@
FeatureInfo[] getSystemAvailableFeatures();
boolean hasSystemFeature(String name);
-
+
void enterSafeMode();
boolean isSafeMode();
void systemReady();
@@ -494,4 +501,7 @@
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
+
+ void grantDefaultPermissions(int userId);
+ void setCarrierAppPackagesProvider(in IPackagesProvider provider);
}
diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/android/content/pm/IPackagesProvider.aidl
similarity index 78%
rename from core/java/android/view/ViewAssistStructure.java
rename to core/java/android/content/pm/IPackagesProvider.aidl
index a66d93c..7d76c88 100644
--- a/core/java/android/view/ViewAssistStructure.java
+++ b/core/java/android/content/pm/IPackagesProvider.aidl
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-package android.view;
+package android.content.pm;
-/**
- * @deprecated Temporary until old apps can move off this.
- */
-@Deprecated
-public abstract class ViewAssistStructure extends ViewStructure {
+/** {@hide} */
+interface IPackagesProvider {
+ String[] getPackages(int userId);
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 5c21c8e..e9ec771 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -294,7 +294,7 @@
*/
public void registerCallback(Callback callback, Handler handler) {
synchronized (this) {
- if (callback != null && !mCallbacks.contains(callback)) {
+ if (callback != null && findCallbackLocked(callback) < 0) {
boolean addedFirstCallback = mCallbacks.size() == 0;
addCallbackLocked(callback, handler);
if (addedFirstCallback) {
@@ -325,17 +325,25 @@
}
}
- private void removeCallbackLocked(Callback callback) {
+ /** @return position in mCallbacks for callback or -1 if not present. */
+ private int findCallbackLocked(Callback callback) {
if (callback == null) {
throw new IllegalArgumentException("Callback cannot be null");
}
final int size = mCallbacks.size();
for (int i = 0; i < size; ++i) {
if (mCallbacks.get(i).mCallback == callback) {
- mCallbacks.remove(i);
- return;
+ return i;
}
}
+ return -1;
+ }
+
+ private void removeCallbackLocked(Callback callback) {
+ int pos = findCallbackLocked(callback);
+ if (pos >= 0) {
+ mCallbacks.remove(pos);
+ }
}
private void addCallbackLocked(Callback callback, Handler handler) {
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 4e7da48..04dbff2 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -109,6 +109,14 @@
public static final int FLAG_COSTS_MONEY = 1<<0;
/**
+ * Flag for {@link #protectionLevel}, corresponding
+ * to the <code>hide</code> value of
+ * {@link android.R.attr#permissionFlags}.
+ * @hide
+ */
+ public static final int PROTECTION_FLAG_HIDE = 1<<1;
+
+ /**
* Additional flags about this permission as given by
* {@link android.R.attr#permissionFlags}.
*/
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 27d14b3..a88b71c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -628,7 +628,7 @@
/**
* <p>List of available high speed video size, fps range and max batch size configurations
* supported by the camera device, in the format of (width, height, fps_min, fps_max, batch_size_max).</p>
- * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in android.control.availableCapabilities,
+ * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities},
* this metadata will list the supported high speed video size, fps range and max batch size
* configurations. All the sizes listed in this configuration will be a subset of the sizes
* reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes }
@@ -675,6 +675,7 @@
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @hide
*/
public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS =
@@ -2679,9 +2680,7 @@
* <p>Camera devices will come in three flavors: LEGACY, LIMITED and FULL.</p>
* <p>A FULL device will support below capabilities:</p>
* <ul>
- * <li>30fps operation at maximum resolution (== sensor resolution) is preferred, more than
- * 20fps is required, for at least uncompressed YUV
- * output. ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li>
+ * <li>BURST_CAPTURE capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li>
* <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li>
* <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR)</li>
* <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
@@ -2689,7 +2688,7 @@
* <li>Arbitrary cropping region ({@link CameraCharacteristics#SCALER_CROPPING_TYPE android.scaler.croppingType} <code>==</code> FREEFORM)</li>
* <li>At least 3 processed (but not stalling) format output streams
* ({@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_PROC android.request.maxNumOutputProc} <code>>=</code> 3)</li>
- * <li>The required stream configuration defined in android.scaler.availableStreamConfigurations</li>
+ * <li>The required stream configurations defined in android.scaler.availableStreamConfigurations</li>
* <li>The required exposure time range defined in {@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
* <li>The required maxFrameDuration defined in {@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li>
* </ul>
@@ -2709,23 +2708,11 @@
* post-processing, arbitrary cropping regions, and has relaxed performance constraints.</p>
* <p>Each higher level supports everything the lower level supports
* in this order: FULL <code>></code> LIMITED <code>></code> LEGACY.</p>
- * <p>A HIGH_RESOLUTION device is equivalent to a FULL device, except that:</p>
- * <ul>
- * <li>At least one output resolution of 8 megapixels or higher in uncompressed YUV is
- * supported at <code>>=</code> 20 fps.</li>
- * <li>Maximum-size (sensor resolution) uncompressed YUV is supported at <code>>=</code> 10
- * fps.</li>
- * <li>For devices that list the RAW capability and support either RAW10 or RAW12 output,
- * maximum-resolution RAW10 or RAW12 capture will operate at least at the rate of
- * maximum-resolution YUV capture, and at least one supported output resolution of
- * 8 megapixels or higher in RAW10 or RAW12 is supported <code>>=</code> 20 fps.</li>
- * </ul>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}</li>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li>
- * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION HIGH_RESOLUTION}</li>
* </ul></p>
* <p>This key is available on all devices.</p>
*
@@ -2743,7 +2730,6 @@
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
- * @see #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION
*/
@PublicKey
public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c656fb8b..5a80585 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -531,37 +531,32 @@
public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5;
/**
- * <p>The camera device supports capturing maximum-resolution
- * images at >= 20 frames per second, in at least the
- * uncompressed YUV format, when post-processing settings
- * are set to FAST.</p>
- * <p>More specifically, this means that a size matching the
- * camera device's active array size is listed as a
- * supported size for the YUV_420_888 format in
- * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}, the minimum frame
- * duration for that format and size is <= 1/20 s, and
- * the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry
- * lists at least one FPS range where the minimum FPS is</p>
- * <blockquote>
- * <p>= 1 / minimumFrameDuration for the maximum-size
- * YUV_420_888 format.</p>
- * </blockquote>
- * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is
- * guaranted to have a value between 0 and 4, inclusive.
- * {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and
- * {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable} are also guaranteed
- * to be <code>true</code> so burst capture with these two locks ON
- * yields consistent image output.</p>
- * <p>On a camera device that reports the HIGH_RESOLUTION hardware
- * level, meaning the device supports very large capture sizes,
- * BURST_CAPTURE means that at least 8-megapixel images can be
- * captured at <code>>=</code> 20 fps, and maximum-resolution images can be
- * captured at <code>>=</code> 10 fps.</p>
+ * <p>The camera device supports capturing high-resolution images at >= 20 frames per
+ * second, in at least the uncompressed YUV format, when post-processing settings are set
+ * to FAST. Additionally, maximum-resolution images can be captured at >= 10 frames
+ * per second. Here, 'high resolution' means at least 8 megapixels, or the maximum
+ * resolution of the device, whichever is smaller.</p>
+ * <p>More specifically, this means that a size matching the camera device's active array
+ * size is listed as a supported size for the {@link android.graphics.ImageFormat#YUV_420_888 } format in either {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } or {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes },
+ * with a minimum frame duration for that format and size of either <= 1/20 s, or
+ * <= 1/10 s, respectively; and the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry
+ * lists at least one FPS range where the minimum FPS is >= 1 / minimumFrameDuration
+ * for the maximum-size YUV_420_888 format. If that maximum size is listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes },
+ * then the list of resolutions for YUV_420_888 from {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } contains at
+ * least one resolution >= 8 megapixels, with a minimum frame duration of <= 1/20
+ * s.</p>
+ * <p>If the device supports the {@link android.graphics.ImageFormat#RAW10 }, {@link android.graphics.ImageFormat#RAW12 }, then those can also be captured at the same rate
+ * as the maximum-size YUV_420_888 resolution is.</p>
+ * <p>If the device supports the PRIVATE_REPROCESSING capability, then the same guarantees
+ * as for the YUV_420_888 format also apply to the {@link android.graphics.ImageFormat#PRIVATE } format.</p>
+ * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is guaranted to have a value between 0
+ * and 4, inclusive. {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable}
+ * are also guaranteed to be <code>true</code> so burst capture with these two locks ON yields
+ * consistent image output.</p>
*
* @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
* @see CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE
* @see CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE
- * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CameraCharacteristics#SYNC_MAX_LATENCY
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -954,13 +949,6 @@
*/
public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2;
- /**
- * <p>This camera device is capable of supporting advanced imaging applications at full rate,
- * and additional high-resolution outputs at lower rates.</p>
- * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
- */
- public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3;
-
//
// Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 9fa6687..75289f7 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -398,7 +398,7 @@
@Override
public int hashCode() {
- return HashCodeHelpers.hashCode(mSettings, mSurfaceSet, mUserTag);
+ return HashCodeHelpers.hashCodeGeneric(mSettings, mSurfaceSet, mUserTag);
}
public static final Parcelable.Creator<CaptureRequest> CREATOR =
@@ -1759,11 +1759,24 @@
* 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
+ * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested,
+ * the camera device will handle thumbnail rotation in one of the following ways:</p>
+ * <ul>
+ * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}
+ * and keep jpeg and thumbnail image data unrotated.</li>
+ * <li>Rotate the jpeg and thumbnail image data and not set
+ * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
+ * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * capture result, so the width and height will be interchanged if 90 or 270 degree
+ * orientation is requested. LEGACY device will always report unrotated thumbnail
+ * size.</li>
+ * </ul>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES
+ * @see CaptureRequest#JPEG_ORIENTATION
*/
@PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index b1fb615..1d31109 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2314,11 +2314,24 @@
* 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
+ * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested,
+ * the camera device will handle thumbnail rotation in one of the following ways:</p>
+ * <ul>
+ * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}
+ * and keep jpeg and thumbnail image data unrotated.</li>
+ * <li>Rotate the jpeg and thumbnail image data and not set
+ * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
+ * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * capture result, so the width and height will be interchanged if 90 or 270 degree
+ * orientation is requested. LEGACY device will always report unrotated thumbnail
+ * size.</li>
+ * </ul>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES
+ * @see CaptureRequest#JPEG_ORIENTATION
*/
@PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java
index 70afe5b..57a080b 100644
--- a/core/java/android/hardware/camera2/DngCreator.java
+++ b/core/java/android/hardware/camera2/DngCreator.java
@@ -284,6 +284,8 @@
* {@code offset + 2 * width * height)} bytes. The width and height of
* the input are taken from the width and height set in the {@link DngCreator} metadata tags,
* and will typically be equal to the width and height of
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}. Prior to
+ * API level 23, this was always the same as
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}.
* The pixel layout in the input is determined from the reported color filter arrangement (CFA)
* set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}. If insufficient
@@ -332,6 +334,8 @@
* {@code offset + 2 * width * height)} bytes. The width and height of
* the input are taken from the width and height set in the {@link DngCreator} metadata tags,
* and will typically be equal to the width and height of
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}. Prior to
+ * API level 23, this was always the same as
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}.
* The pixel layout in the input is determined from the reported color filter arrangement (CFA)
* set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}. If insufficient
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 10dd8ae..7e50fd9 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -842,11 +842,19 @@
CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
ReprocessFormatsMap inputOutputFormatsMap = getBase(
CameraCharacteristics.SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP);
-
+ int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+ boolean listHighResolution = false;
+ for (int capability : capabilities) {
+ if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE) {
+ listHighResolution = true;
+ break;
+ }
+ }
return new StreamConfigurationMap(
configurations, minFrameDurations, stallDurations,
depthConfigurations, depthMinFrameDurations, depthStallDurations,
- highSpeedVideoConfigurations, inputOutputFormatsMap);
+ highSpeedVideoConfigurations, inputOutputFormatsMap,
+ listHighResolution);
}
private <T> Integer getMaxRegions(Key<T> key) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 2fb3203..e786707 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -605,6 +605,14 @@
return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
}
+ /**
+ * Query the surface for its currently configured dataspace
+ */
+ public static int detectSurfaceDataspace(Surface surface) throws BufferQueueAbandonedException {
+ checkNotNull(surface);
+ return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface));
+ }
+
static void configureSurface(Surface surface, int width, int height,
int pixelFormat) throws BufferQueueAbandonedException {
checkNotNull(surface);
@@ -702,6 +710,8 @@
private static native int nativeDetectSurfaceType(Surface surface);
+ private static native int nativeDetectSurfaceDataspace(Surface surface);
+
private static native int nativeDetectSurfaceDimens(Surface surface,
/*out*/int[/*2*/] dimens);
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index c6ea488..639ad60 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -20,14 +20,16 @@
import android.graphics.PixelFormat;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.utils.SurfaceUtils;
import android.hardware.camera2.legacy.LegacyCameraDevice;
import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException;
import android.view.Surface;
import android.util.Range;
import android.util.Size;
+import android.util.SparseIntArray;
import java.util.Arrays;
import java.util.HashMap;
@@ -79,7 +81,8 @@
* @param stallDurations a non-{@code null} array of {@link StreamConfigurationDuration}
* @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if
* camera device does not support high speed video recording
- *
+ * @param listHighResolution a flag indicating whether the device supports BURST_CAPTURE
+ * and thus needs a separate list of slow high-resolution output sizes
* @throws NullPointerException if any of the arguments except highSpeedVideoConfigurations
* were {@code null} or any subelements were {@code null}
*
@@ -93,10 +96,12 @@
StreamConfigurationDuration[] depthMinFrameDurations,
StreamConfigurationDuration[] depthStallDurations,
HighSpeedVideoConfiguration[] highSpeedVideoConfigurations,
- ReprocessFormatsMap inputOutputFormatsMap) {
+ ReprocessFormatsMap inputOutputFormatsMap,
+ boolean listHighResolution) {
mConfigurations = checkArrayElementsNotNull(configurations, "configurations");
mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations");
mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations");
+ mListHighResolution = listHighResolution;
if (depthConfigurations == null) {
mDepthConfigurations = new StreamConfiguration[0];
@@ -120,15 +125,27 @@
// For each format, track how many sizes there are available to configure
for (StreamConfiguration config : configurations) {
- HashMap<Integer, Integer> map = config.isOutput() ? mOutputFormats : mInputFormats;
-
- Integer count = map.get(config.getFormat());
-
- if (count == null) {
- count = 0;
+ int fmt = config.getFormat();
+ SparseIntArray map = null;
+ if (config.isOutput()) {
+ mAllOutputFormats.put(fmt, mAllOutputFormats.get(fmt) + 1);
+ long duration = 0;
+ if (mListHighResolution) {
+ for (StreamConfigurationDuration configurationDuration : mMinFrameDurations) {
+ if (configurationDuration.getFormat() == fmt &&
+ configurationDuration.getWidth() == config.getSize().getWidth() &&
+ configurationDuration.getHeight() == config.getSize().getHeight()) {
+ duration = configurationDuration.getDuration();
+ break;
+ }
+ }
+ }
+ map = duration <= DURATION_20FPS_NS ?
+ mOutputFormats : mHighResOutputFormats;
+ } else {
+ map = mInputFormats;
}
-
- map.put(config.getFormat(), count + 1);
+ map.put(fmt, map.get(fmt) + 1);
}
// For each depth format, track how many sizes there are available to configure
@@ -138,16 +155,11 @@
continue;
}
- Integer count = mDepthOutputFormats.get(config.getFormat());
-
- if (count == null) {
- count = 0;
- }
-
- mDepthOutputFormats.put(config.getFormat(), count + 1);
+ mDepthOutputFormats.put(config.getFormat(),
+ mDepthOutputFormats.get(config.getFormat()) + 1);
}
- if (!mOutputFormats.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
+ if (mOutputFormats.indexOfKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) < 0) {
throw new AssertionError(
"At least one stream configuration for IMPLEMENTATION_DEFINED must exist");
}
@@ -241,7 +253,7 @@
* @return a non-empty array of sizes, or {@code null} if the format was not available.
*/
public Size[] getInputSizes(final int format) {
- return getPublicFormatSizes(format, /*output*/false);
+ return getPublicFormatSizes(format, /*output*/false, /*highRes*/false);
}
/**
@@ -274,9 +286,9 @@
int internalFormat = imageFormatToInternal(format);
int dataspace = imageFormatToDataspace(format);
if (dataspace == HAL_DATASPACE_DEPTH) {
- return mDepthOutputFormats.containsKey(internalFormat);
+ return mDepthOutputFormats.indexOfKey(internalFormat) >= 0;
} else {
- return getFormatsMap(/*output*/true).containsKey(internalFormat);
+ return getFormatsMap(/*output*/true).indexOfKey(internalFormat) >= 0;
}
}
@@ -378,27 +390,24 @@
public boolean isOutputSupportedFor(Surface surface) {
checkNotNull(surface, "surface must not be null");
- Size surfaceSize;
- int surfaceFormat = -1;
- try {
- surfaceSize = LegacyCameraDevice.getSurfaceSize(surface);
- surfaceFormat = LegacyCameraDevice.detectSurfaceType(surface);
- } catch(BufferQueueAbandonedException e) {
- throw new IllegalArgumentException("Abandoned surface", e);
- }
+ Size surfaceSize = SurfaceUtils.getSurfaceSize(surface);
+ int surfaceFormat = SurfaceUtils.getSurfaceFormat(surface);
+ int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
// See if consumer is flexible.
- boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface);
+ boolean isFlexible = SurfaceUtils.isFlexibleConsumer(surface);
// Override RGB formats to IMPLEMENTATION_DEFINED, b/9487482
if ((surfaceFormat >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
surfaceFormat <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
- surfaceFormat = LegacyMetadataMapper.HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ surfaceFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
}
- for (StreamConfiguration config : mConfigurations) {
+ StreamConfiguration[] configs =
+ surfaceDataspace != HAL_DATASPACE_DEPTH ? mConfigurations : mDepthConfigurations;
+ for (StreamConfiguration config : configs) {
if (config.getFormat() == surfaceFormat && config.isOutput()) {
- // Mathing format, either need exact size match, or a flexible consumer
+ // Matching format, either need exact size match, or a flexible consumer
// and a size no bigger than MAX_DIMEN_FOR_ROUNDING
if (config.getSize().equals(surfaceSize)) {
return true;
@@ -414,12 +423,12 @@
/**
* Get a list of sizes compatible with {@code klass} to use as an output.
*
- * <p>Since some of the supported classes may support additional formats beyond
+ * <p>Some of the supported classes may support additional formats beyond
* {@link ImageFormat#PRIVATE}; this function only returns
* sizes for {@link ImageFormat#PRIVATE}. For example, {@link android.media.ImageReader}
* supports {@link ImageFormat#YUV_420_888} and {@link ImageFormat#PRIVATE}, this method will
* only return the sizes for {@link ImageFormat#PRIVATE} for {@link android.media.ImageReader}
- * class .</p>
+ * class.</p>
*
* <p>If a well-defined format such as {@code NV21} is required, use
* {@link #getOutputSizes(int)} instead.</p>
@@ -444,7 +453,7 @@
}
return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
- HAL_DATASPACE_UNKNOWN,/*output*/true);
+ HAL_DATASPACE_UNKNOWN,/*output*/true, /*highRes*/false);
}
/**
@@ -453,6 +462,14 @@
* <p>The {@code format} should be a supported format (one of the formats returned by
* {@link #getOutputFormats}).</p>
*
+ * As of API level 23, the {@link #getHighResolutionOutputSizes} method can be used on devices
+ * that support the
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}
+ * capability to get a list of high-resolution output sizes that cannot operate at the preferred
+ * 20fps rate. This means that for some supported formats, this method will return an empty
+ * list, if all the supported resolutions operate at below 20fps. For devices that do not
+ * support the BURST_CAPTURE capability, all output resolutions are listed through this method.
+ *
* @param format an image format from {@link ImageFormat} or {@link PixelFormat}
* @return
* an array of supported sizes,
@@ -463,36 +480,40 @@
* @see #getOutputFormats
*/
public Size[] getOutputSizes(int format) {
- return getPublicFormatSizes(format, /*output*/true);
+ return getPublicFormatSizes(format, /*output*/true, /*highRes*/ false);
}
/**
* Get a list of supported high speed video recording sizes.
- *
- * <p> When HIGH_SPEED_VIDEO is supported in
- * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this
- * method will list the supported high speed video size configurations. All the sizes listed
- * will be a subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling
- * formats (typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12)</p>
- *
- * <p> To enable high speed video recording, application must set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests and select the video size from this method and
+ * <p>
+ * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is
+ * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will
+ * list the supported high speed video size configurations. All the sizes listed will be a
+ * subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling formats
+ * (typically {@link ImageFormat#PRIVATE} {@link ImageFormat#YUV_420_888}, etc.)
+ * </p>
+ * <p>
+ * To enable high speed video recording, application must create a constrained create high speed
+ * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit
+ * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList}
+ * to this session. The application must select the video size from this method and
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from
- * {@link #getHighSpeedVideoFpsRangesFor} to configure the recording and preview streams and
- * setup the recording requests. For example, if the application intends to do high speed
- * recording, it can select the maximum size reported by this method to configure output
- * streams. Note that for the use case of multiple output streams, application must select one
- * unique size from this method to use. Otherwise a request error might occur. Once the size is
+ * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and
+ * generate the high speed request list. For example, if the application intends to do high
+ * speed recording, it can select the maximum size reported by this method to create high speed
+ * capture session. Note that for the use case of multiple output streams, application must
+ * select one unique size from this method to use (e.g., preview and recording streams must have
+ * the same size). Otherwise, the high speed session creation will fail. Once the size is
* selected, application can get the supported FPS ranges by
* {@link #getHighSpeedVideoFpsRangesFor}, and use these FPS ranges to setup the recording
- * requests.</p>
+ * request lists via {@link CameraDevice#createConstrainedHighSpeedRequestList}.
+ * </p>
*
- * @return
- * an array of supported high speed video recording sizes
- *
+ * @return an array of supported high speed video recording sizes
* @see #getHighSpeedVideoFpsRangesFor(Size)
+ * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
+ * @see CameraDevice#createConstrainedHighSpeedCaptureSession
+ * @see CameraDevice#createConstrainedHighSpeedRequestList
*/
public Size[] getHighSpeedVideoSizes() {
Set<Size> keySet = mHighSpeedVideoSizeMap.keySet();
@@ -501,26 +522,25 @@
/**
* Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size.
- *
- * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p>
- *
- * <p> For normal video recording use case, where some application will NOT set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in
- * this method must not be used to setup capture requests, or it will cause request error.</p>
+ * <p>
+ * See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.
+ * </p>
+ * <p>
+ * The {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in this method
+ * must not be used to setup capture requests that are submitted to unconstrained capture
+ * sessions, or it will result in {@link IllegalArgumentException IllegalArgumentExceptions}.
+ * </p>
+ * <p>
+ * See {@link #getHighSpeedVideoFpsRanges} for the characteristics of the returned FPS ranges.
+ * </p>
*
* @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()}
- * @return
- * An array of FPS range to use with
- * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE TARGET_FPS_RANGE} when using
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene
- * mode.
- * The upper bound of returned ranges is guaranteed to be larger or equal to 60.
- *
+ * @return an array of supported high speed video recording FPS ranges The upper bound of
+ * returned ranges is guaranteed to be greater than or equal to 120.
* @throws IllegalArgumentException if input size does not exist in the return value of
- * getHighSpeedVideoSizes
+ * getHighSpeedVideoSizes
* @see #getHighSpeedVideoSizes()
+ * @see #getHighSpeedVideoFpsRanges()
*/
public Range<Integer>[] getHighSpeedVideoFpsRangesFor(Size size) {
Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size);
@@ -542,34 +562,46 @@
/**
* Get a list of supported high speed video recording FPS ranges.
- *
- * <p> When HIGH_SPEED_VIDEO is supported in
- * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this
- * method will list the supported high speed video FPS range configurations. Application can
- * then use {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned
- * FPS range.</p>
- *
- * <p> To enable high speed video recording, application must set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests and select the video size from {@link #getHighSpeedVideoSizesFor} and
+ * <p>
+ * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is
+ * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will
+ * list the supported high speed video FPS range configurations. Application can then use
+ * {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned FPS range.
+ * </p>
+ * <p>
+ * To enable high speed video recording, application must create a constrained create high speed
+ * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit
+ * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList}
+ * to this session. The application must select the video size from this method and
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from
- * this method to configure the recording and preview streams and setup the recording requests.
- * For example, if the application intends to do high speed recording, it can select one FPS
- * range reported by this method, query the video sizes corresponding to this FPS range by
- * {@link #getHighSpeedVideoSizesFor} and select one of reported sizes to configure output
- * streams. Note that for the use case of multiple output streams, application must select one
- * unique size from {@link #getHighSpeedVideoSizesFor}, and use it for all output streams.
- * Otherwise a request error might occur when attempting to enable
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}.
- * Once the stream is configured, application can set the FPS range in the recording requests.
+ * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and
+ * generate the high speed request list. For example, if the application intends to do high
+ * speed recording, it can select one FPS range reported by this method, query the video sizes
+ * corresponding to this FPS range by {@link #getHighSpeedVideoSizesFor} and use one of reported
+ * sizes to create a high speed capture session. Note that for the use case of multiple output
+ * streams, application must select one unique size from this method to use (e.g., preview and
+ * recording streams must have the same size). Otherwise, the high speed session creation will
+ * fail. Once the high speed capture session is created, the application can set the FPS range
+ * in the recording request lists via
+ * {@link CameraDevice#createConstrainedHighSpeedRequestList}.
+ * </p>
+ * <p>
+ * The FPS ranges reported by this method will have below characteristics:
+ * <li>The fpsMin and fpsMax will be a multiple 30fps.</li>
+ * <li>The fpsMin will be no less than 30fps, the fpsMax will be no less than 120fps.</li>
+ * <li>At least one range will be a fixed FPS range where fpsMin == fpsMax.</li>
+ * <li>For each fixed FPS range, there will be one corresponding variable FPS range [30,
+ * fps_max]. These kinds of FPS ranges are suitable for preview-only use cases where the
+ * application doesn't want the camera device always produce higher frame rate than the display
+ * refresh rate.</li>
* </p>
*
- * @return
- * an array of supported high speed video recording FPS ranges
- * The upper bound of returned ranges is guaranteed to be larger or equal to 60.
- *
+ * @return an array of supported high speed video recording FPS ranges The upper bound of
+ * returned ranges is guaranteed to be larger or equal to 120.
* @see #getHighSpeedVideoSizesFor
+ * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
+ * @see CameraDevice#createConstrainedHighSpeedCaptureSession
+ * @see CameraDevice#createConstrainedHighSpeedRequestList
*/
@SuppressWarnings("unchecked")
public Range<Integer>[] getHighSpeedVideoFpsRanges() {
@@ -578,21 +610,13 @@
}
/**
- * Get the supported video sizes for input FPS range.
+ * Get the supported video sizes for an input high speed FPS range.
*
- * <p> See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.</p>
- *
- * <p> For normal video recording use case, where the application will NOT set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in
- * this method must not be used to setup capture requests, or it will cause request error.</p>
+ * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p>
*
* @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()}
- * @return
- * An array of video sizes to configure output stream when using
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene
- * mode.
+ * @return An array of video sizes to create high speed capture sessions for high speed streaming
+ * use cases.
*
* @throws IllegalArgumentException if input FPS range does not exist in the return value of
* getHighSpeedVideoFpsRanges
@@ -616,6 +640,32 @@
}
/**
+ * Get a list of supported high resolution sizes, which cannot operate at full BURST_CAPTURE
+ * rate.
+ *
+ * <p>This includes all output sizes that cannot meet the 20 fps frame rate requirements for the
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}
+ * capability. This does not include the stall duration, so for example, a JPEG or RAW16 output
+ * resolution with a large stall duration but a minimum frame duration that's above 20 fps will
+ * still be listed in the regular {@link #getOutputSizes} list. All the sizes on this list are
+ * still guaranteed to operate at a rate of at least 10 fps, not including stall duration.</p>
+ *
+ * <p>For a device that does not support the BURST_CAPTURE capability, this list will be
+ * {@code null}, since resolutions in the {@link #getOutputSizes} list are already not
+ * guaranteed to meet >= 20 fps rate requirements. For a device that does support the
+ * BURST_CAPTURE capability, this list may be empty, if all supported resolutions meet the 20
+ * fps requirement.</p>
+ *
+ * @return an array of supported slower high-resolution sizes, or {@code null} if the
+ * BURST_CAPTURE capability is not supported
+ */
+ public Size[] getHighResolutionOutputSizes(int format) {
+ if (!mListHighResolution) return null;
+
+ return getPublicFormatSizes(format, /*output*/true, /*highRes*/ true);
+ }
+
+ /**
* Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration}
* for the format/size combination (in nanoseconds).
*
@@ -867,6 +917,7 @@
return Arrays.equals(mConfigurations, other.mConfigurations) &&
Arrays.equals(mMinFrameDurations, other.mMinFrameDurations) &&
Arrays.equals(mStallDurations, other.mStallDurations) &&
+ Arrays.equals(mDepthConfigurations, other.mDepthConfigurations) &&
Arrays.equals(mHighSpeedVideoConfigurations,
other.mHighSpeedVideoConfigurations);
}
@@ -879,18 +930,31 @@
@Override
public int hashCode() {
// XX: do we care about order?
- return HashCodeHelpers.hashCode(
+ return HashCodeHelpers.hashCodeGeneric(
mConfigurations, mMinFrameDurations,
- mStallDurations, mHighSpeedVideoConfigurations);
+ mStallDurations,
+ mDepthConfigurations, mHighSpeedVideoConfigurations);
}
// Check that the argument is supported by #getOutputFormats or #getInputFormats
private int checkArgumentFormatSupported(int format, boolean output) {
checkArgumentFormat(format);
- int[] formats = output ? getOutputFormats() : getInputFormats();
- for (int i = 0; i < formats.length; ++i) {
- if (format == formats[i]) {
+ int internalFormat = imageFormatToInternal(format);
+ int internalDataspace = imageFormatToDataspace(format);
+
+ if (output) {
+ if (internalDataspace == HAL_DATASPACE_DEPTH) {
+ if (mDepthOutputFormats.indexOfKey(internalFormat) >= 0) {
+ return format;
+ }
+ } else {
+ if (mAllOutputFormats.indexOfKey(internalFormat) >= 0) {
+ return format;
+ }
+ }
+ } else {
+ if (mInputFormats.indexOfKey(internalFormat) >= 0) {
return format;
}
}
@@ -1175,7 +1239,7 @@
return formats;
}
- private Size[] getPublicFormatSizes(int format, boolean output) {
+ private Size[] getPublicFormatSizes(int format, boolean output, boolean highRes) {
try {
checkArgumentFormatSupported(format, output);
} catch (IllegalArgumentException e) {
@@ -1185,36 +1249,57 @@
int internalFormat = imageFormatToInternal(format);
int dataspace = imageFormatToDataspace(format);
- return getInternalFormatSizes(internalFormat, dataspace, output);
+ return getInternalFormatSizes(internalFormat, dataspace, output, highRes);
}
- private Size[] getInternalFormatSizes(int format, int dataspace, boolean output) {
+ private Size[] getInternalFormatSizes(int format, int dataspace,
+ boolean output, boolean highRes) {
+ SparseIntArray formatsMap =
+ !output ? mInputFormats :
+ dataspace == HAL_DATASPACE_DEPTH ? mDepthOutputFormats :
+ highRes ? mHighResOutputFormats :
+ mOutputFormats;
- HashMap<Integer, Integer> formatsMap =
- (dataspace == HAL_DATASPACE_DEPTH) ? mDepthOutputFormats : getFormatsMap(output);
-
- Integer sizesCount = formatsMap.get(format);
- if (sizesCount == null) {
+ int sizesCount = formatsMap.get(format);
+ if ( ((!output || dataspace == HAL_DATASPACE_DEPTH) && sizesCount == 0) ||
+ (output && dataspace != HAL_DATASPACE_DEPTH && mAllOutputFormats.get(format) == 0)) {
+ // Only throw if this is really not supported at all
throw new IllegalArgumentException("format not available");
}
- int len = sizesCount;
- Size[] sizes = new Size[len];
+ Size[] sizes = new Size[sizesCount];
int sizeIndex = 0;
StreamConfiguration[] configurations =
(dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;
-
for (StreamConfiguration config : configurations) {
- if (config.getFormat() == format && config.isOutput() == output) {
+ int fmt = config.getFormat();
+ if (fmt == format && config.isOutput() == output) {
+ if (output) {
+ // Filter slow high-res output formats; include for
+ // highRes, remove for !highRes
+ long duration = 0;
+ for (int i = 0; i < mMinFrameDurations.length; i++) {
+ StreamConfigurationDuration d = mMinFrameDurations[i];
+ if (d.getFormat() == fmt &&
+ d.getWidth() == config.getSize().getWidth() &&
+ d.getHeight() == config.getSize().getHeight()) {
+ duration = d.getDuration();
+ break;
+ }
+ }
+ if (highRes != (duration > DURATION_20FPS_NS)) {
+ continue;
+ }
+ }
sizes[sizeIndex++] = config.getSize();
}
}
- if (sizeIndex != len) {
+ if (sizeIndex != sizesCount) {
throw new AssertionError(
- "Too few sizes (expected " + len + ", actual " + sizeIndex + ")");
+ "Too few sizes (expected " + sizesCount + ", actual " + sizeIndex + ")");
}
return sizes;
@@ -1226,14 +1311,16 @@
int i = 0;
- for (int format : getFormatsMap(output).keySet()) {
+ SparseIntArray map = getFormatsMap(output);
+ for (int j = 0; j < map.size(); j++) {
+ int format = map.keyAt(j);
if (format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
formats[i++] = imageFormatToPublic(format);
}
}
if (output) {
- for (int format : mDepthOutputFormats.keySet()) {
- formats[i++] = depthFormatToPublic(format);
+ for (int j = 0; j < mDepthOutputFormats.size(); j++) {
+ formats[i++] = depthFormatToPublic(mDepthOutputFormats.keyAt(j));
}
}
if (formats.length != i) {
@@ -1244,14 +1331,14 @@
}
/** Get the format -> size count map for either output or input formats */
- private HashMap<Integer, Integer> getFormatsMap(boolean output) {
- return output ? mOutputFormats : mInputFormats;
+ private SparseIntArray getFormatsMap(boolean output) {
+ return output ? mAllOutputFormats : mInputFormats;
}
private long getInternalFormatDuration(int format, int dataspace, Size size, int duration) {
// assume format is already checked, since its internal
- if (!arrayContains(getInternalFormatSizes(format, dataspace, /*output*/true), size)) {
+ if (!isSupportedInternalConfiguration(format, dataspace, size)) {
throw new IllegalArgumentException("size was not supported");
}
@@ -1289,10 +1376,9 @@
/** Count the number of publicly-visible output formats */
private int getPublicFormatCount(boolean output) {
- HashMap<Integer, Integer> formatsMap = getFormatsMap(output);
-
+ SparseIntArray formatsMap = getFormatsMap(output);
int size = formatsMap.size();
- if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
+ if (formatsMap.indexOfKey(HAL_PIXEL_FORMAT_RAW_OPAQUE) >= 0) {
size -= 1;
}
if (output) {
@@ -1316,6 +1402,21 @@
return false;
}
+ private boolean isSupportedInternalConfiguration(int format, int dataspace,
+ Size size) {
+ StreamConfiguration[] configurations =
+ (dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;
+
+ for (int i = 0; i < configurations.length; i++) {
+ if (configurations[i].getFormat() == format &&
+ configurations[i].getSize().equals(size)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Return this {@link StreamConfigurationMap} as a string representation.
*
@@ -1351,6 +1452,8 @@
StringBuilder sb = new StringBuilder("StreamConfiguration(");
appendOutputsString(sb);
sb.append(", ");
+ appendHighResOutputsString(sb);
+ sb.append(", ");
appendInputsString(sb);
sb.append(", ");
appendValidOutputFormatsForInputString(sb);
@@ -1381,6 +1484,27 @@
sb.append(")");
}
+ private void appendHighResOutputsString(StringBuilder sb) {
+ sb.append("HighResolutionOutputs(");
+ int[] formats = getOutputFormats();
+ for (int format : formats) {
+ Size[] sizes = getHighResolutionOutputSizes(format);
+ if (sizes == null) continue;
+ for (Size size : sizes) {
+ long minFrameDuration = getOutputMinFrameDuration(format, size);
+ long stallDuration = getOutputStallDuration(format, size);
+ sb.append(String.format("[w:%d, h:%d, format:%s(%d), min_duration:%d, " +
+ "stall:%d], ", size.getWidth(), size.getHeight(), formatToString(format),
+ format, minFrameDuration, stallDuration));
+ }
+ }
+ // Remove the pending ", "
+ if (sb.charAt(sb.length() - 1) == ' ') {
+ sb.delete(sb.length() - 2, sb.length());
+ }
+ sb.append(")");
+ }
+
private void appendInputsString(StringBuilder sb) {
sb.append("Inputs(");
int[] formats = getInputFormats();
@@ -1479,15 +1603,21 @@
}
// from system/core/include/system/graphics.h
+ private static final int HAL_PIXEL_FORMAT_RAW16 = 0x20;
private static final int HAL_PIXEL_FORMAT_BLOB = 0x21;
private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;
+ private static final int HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23;
private static final int HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24;
+ private static final int HAL_PIXEL_FORMAT_RAW10 = 0x25;
+ private static final int HAL_PIXEL_FORMAT_RAW12 = 0x26;
private static final int HAL_PIXEL_FORMAT_Y16 = 0x20363159;
+
private static final int HAL_DATASPACE_UNKNOWN = 0x0;
private static final int HAL_DATASPACE_JFIF = 0x101;
private static final int HAL_DATASPACE_DEPTH = 0x1000;
+ private static final long DURATION_20FPS_NS = 50000000L;
/**
* @see #getDurations(int, int)
*/
@@ -1505,15 +1635,20 @@
private final HighSpeedVideoConfiguration[] mHighSpeedVideoConfigurations;
private final ReprocessFormatsMap mInputOutputFormatsMap;
- /** ImageFormat -> num output sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mOutputFormats =
- new HashMap<Integer, Integer>();
- /** ImageFormat -> num input sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mInputFormats =
- new HashMap<Integer, Integer>();
- /** ImageFormat -> num depth output sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mDepthOutputFormats =
- new HashMap<Integer, Integer>();
+ private final boolean mListHighResolution;
+
+ /** internal format -> num output sizes mapping, not including slow high-res sizes, for
+ * non-depth dataspaces */
+ private final SparseIntArray mOutputFormats = new SparseIntArray();
+ /** internal format -> num output sizes mapping for slow high-res sizes, for non-depth
+ * dataspaces */
+ private final SparseIntArray mHighResOutputFormats = new SparseIntArray();
+ /** internal format -> num output sizes mapping for all non-depth dataspaces */
+ private final SparseIntArray mAllOutputFormats = new SparseIntArray();
+ /** internal format -> num input sizes mapping, for input reprocessing formats */
+ private final SparseIntArray mInputFormats = new SparseIntArray();
+ /** internal format -> num depth output sizes mapping, for HAL_DATASPACE_DEPTH */
+ private final SparseIntArray mDepthOutputFormats = new SparseIntArray();
/** High speed video Size -> FPS range count mapping*/
private final HashMap</*HighSpeedVideoSize*/Size, /*Count*/Integer> mHighSpeedVideoSizeMap =
new HashMap<Size, Integer>();
@@ -1522,4 +1657,3 @@
mHighSpeedVideoFpsRangeMap = new HashMap<Range<Integer>, Integer>();
}
-
diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
index 398a7e9..2d7bbaa 100644
--- a/core/java/android/hardware/camera2/params/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -277,7 +277,7 @@
return mHashCode;
}
- mHashCode = HashCodeHelpers.hashCode(mRed, mGreen, mBlue);
+ mHashCode = HashCodeHelpers.hashCodeGeneric(mRed, mGreen, mBlue);
mHashCalculated = true;
return mHashCode;
diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
index 7b4aa09..731da8b 100644
--- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
+++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
@@ -30,7 +30,7 @@
*
* @return the numeric hash code
*/
- public static int hashCode(int[] array) {
+ public static int hashCode(int... array) {
if (array == null) {
return 0;
}
@@ -60,7 +60,7 @@
*
* @return the numeric hash code
*/
- public static int hashCode(float[] array) {
+ public static int hashCode(float... array) {
if (array == null) {
return 0;
}
@@ -83,7 +83,7 @@
*
* @return the numeric hash code
*/
- public static <T> int hashCode(T[] array) {
+ public static <T> int hashCodeGeneric(T... array) {
if (array == null) {
return 0;
}
@@ -97,56 +97,4 @@
return h;
}
- public static <T> int hashCode(T a) {
- return (a == null) ? 0 : a.hashCode();
- }
-
- public static <T> int hashCode(T a, T b) {
- int h = hashCode(a);
-
- int x = (b == null) ? 0 : b.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static <T> int hashCode(T a, T b, T c) {
- int h = hashCode(a, b);
-
- int x = (c == null) ? 0 : c.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static <T> int hashCode(T a, T b, T c, T d) {
- int h = hashCode(a, b, c);
-
- int x = (d == null) ? 0 : d.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static int hashCode(int x) {
- return hashCode(new int[] { x } );
- }
-
- public static int hashCode(int x, int y) {
- return hashCode(new int[] { x, y } );
- }
-
- public static int hashCode(int x, int y, int z) {
- return hashCode(new int[] { x, y, z } );
- }
-
- public static int hashCode(int x, int y, int z, int w) {
- return hashCode(new int[] { x, y, z, w } );
- }
-
- public static int hashCode(int x, int y, int z, int w, int t) {
- return hashCode(new int[] { x, y, z, w, t } );
- }
-
-
}
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index 40005a5..064b21a 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -79,4 +79,30 @@
throw new IllegalArgumentException("Surface was abandoned", e);
}
}
+
+ /**
+ * Get the Surface dataspace.
+ *
+ * @param surface The surface to be queried for dataspace.
+ * @return dataspace of the surface.
+ *
+ * @throws IllegalArgumentException if the surface is already abandoned.
+ */
+ public static int getSurfaceDataspace(Surface surface) {
+ try {
+ return LegacyCameraDevice.detectSurfaceDataspace(surface);
+ } catch (BufferQueueAbandonedException e) {
+ throw new IllegalArgumentException("Surface was abandoned", e);
+ }
+ }
+
+ /**
+ * Return true is the consumer is one of the consumers that can accept
+ * producer overrides of the default dimensions and format.
+ *
+ */
+ public static boolean isFlexibleConsumer(Surface output) {
+ return LegacyCameraDevice.isFlexibleConsumer(output);
+ }
+
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b9f7365..80476ea 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2110,6 +2110,8 @@
* can automatically log in to a captive portal without user intervention.
*
* @param network The {@link Network} of the network that is being evaluated.
+ *
+ * @hide
*/
public void onPreCheck(Network network) {}
@@ -2379,6 +2381,14 @@
* Status of the request can be followed by listening to the various
* callbacks described in {@link NetworkCallback}. The {@link Network}
* can be used to direct traffic to the network.
+ * <p>It is presently unsupported to request a network with mutable
+ * {@link NetworkCapabilities} such as
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
+ * as these {@code NetworkCapabilities} represent states that a particular
+ * network may never attain, and whether a network will attain these states
+ * is unknown prior to bringing up the network so the framework does not
+ * know how to go about satisfing a request with these capabilities.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
@@ -2386,6 +2396,8 @@
* @param networkCallback The {@link NetworkCallback} to be utilized for this
* request. Note the callback must not be shared - they
* uniquely specify this request.
+ * @throws IllegalArgumentException if {@code request} specifies any mutable
+ * {@code NetworkCapabilities}.
*/
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
@@ -2467,12 +2479,22 @@
* <p>
* The request may be released normally by calling
* {@link #releaseNetworkRequest(android.app.PendingIntent)}.
+ * <p>It is presently unsupported to request a network with either
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
+ * as these {@code NetworkCapabilities} represent states that a particular
+ * network may never attain, and whether a network will attain these states
+ * is unknown prior to bringing up the network so the framework does not
+ * know how to go about satisfing a request with these capabilities.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param request {@link NetworkRequest} describing this request.
* @param operation Action to perform when the network is available (corresponds
* to the {@link NetworkCallback#onAvailable} call. Typically
* comes from {@link PendingIntent#getBroadcast}. Cannot be null.
+ * @throws IllegalArgumentException if {@code request} contains either
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
*/
public void requestNetwork(NetworkRequest request, PendingIntent operation) {
checkPendingIntent(operation);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index cf747cf..658051c 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -173,12 +173,17 @@
* Indicates that connectivity on this network was successfully validated. For example, for a
* network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
* detected.
- * @hide
*/
public static final int NET_CAPABILITY_VALIDATED = 16;
+ /**
+ * Indicates that this network was found to have a captive portal in place last time it was
+ * probed.
+ */
+ public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;
/**
* Adds the given capability to this {@code NetworkCapability} instance.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 593f804..7fda30a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -142,9 +142,9 @@
public static final int CAMERA_TURNED_ON = 17;
/**
- * A constant indicating a doze wake lock timer.
+ * A constant indicating a draw wake lock timer.
*/
- public static final int WAKE_TYPE_DOZE = 18;
+ public static final int WAKE_TYPE_DRAW = 18;
/**
* Include all of the data in the stats, including previously saved data.
@@ -3839,7 +3839,7 @@
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
= u.getWakelockStats();
long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
- long totalDozeWakelock = 0;
+ long totalDrawWakelock = 0;
int countWakelock = 0;
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
final Uid.Wakelock wl = wakelocks.valueAt(iw);
@@ -3854,8 +3854,8 @@
"partial", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
"window", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DOZE), rawRealtime,
- "doze", which, linePrefix);
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
+ "draw", which, linePrefix);
sb.append(" realtime");
pw.println(sb.toString());
uidActivity = true;
@@ -3867,7 +3867,7 @@
rawRealtime, which);
totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
rawRealtime, which);
- totalDozeWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DOZE),
+ totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
rawRealtime, which);
}
if (countWakelock > 1) {
@@ -3898,13 +3898,13 @@
formatTimeMs(sb, totalWindowWakelock);
sb.append("window");
}
- if (totalDozeWakelock != 0) {
+ if (totalDrawWakelock != 0) {
if (needComma) {
sb.append(",");
}
needComma = true;
- formatTimeMs(sb, totalDozeWakelock);
- sb.append("doze");
+ formatTimeMs(sb, totalDrawWakelock);
+ sb.append("draw");
}
sb.append(" realtime");
pw.println(sb.toString());
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 87e8c5e..97b85e2 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1469,13 +1469,30 @@
* </tr>
* <tr>
* <td>art.gc.gc-count-rate-histogram</td>
- * <td>The histogram of the number of garbage collection runs per 10 seconds.</td>
+ * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage
+ * collection runs that have occurred over the last 10
+ * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate
+ * samples taken since the process began. The histogram can be used to identify
+ * instances of high rates of garbage collection runs. For example, a histogram
+ * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time
+ * there are between 0 and 2 garbage collection runs every 10 seconds, but there
+ * were 8 distinct 10-second intervals in which 5 garbage collection runs
+ * occurred.</td>
* <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td>
* <td>23</td>
* </tr>
* <tr>
* <td>art.gc.blocking-gc-count-rate-histogram</td>
- * <td>The histogram of the number of garbage collection runs per 10 seconds.</td>
+ * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of
+ * blocking garbage collection runs that have occurred over the last 10
+ * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the
+ * blocking-gc-count-rate samples taken since the process began. The histogram
+ * can be used to identify instances of high rates of blocking garbage
+ * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that
+ * most of the time there are zero blocking garbage collection runs every 10
+ * seconds, but there was one 10-second interval in which one blocking garbage
+ * collection run occurred, and there was one interval in which two blocking
+ * garbage collection runs occurred.</td>
* <td>{@code 0:99269,1:1,2:1}</td>
* <td>23</td>
* </tr>
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 1cc2d33..f10b982 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1919,9 +1919,9 @@
for (int i = 0; i < numViolations; ++i) {
if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i);
ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
- if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 10000) {
+ if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 30000) {
String front = info.crashInfo.stackTrace.substring(256);
- // 10000 characters is way too large for this to be any sane kind of
+ // 30000 characters is way too large for this to be any sane kind of
// strict mode collection of stacks. We've had a problem where we leave
// strict mode violations associated with the thread, and it keeps tacking
// more and more stacks on to the violations. Looks like we're in this casse,
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 00350ec..9770941 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -449,6 +449,22 @@
public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
/**
+ * This user restriction has an effect only in a managed profile.
+ * If set:
+ * Intent filters of activities in the parent profile with action
+ * {@link android.content.Intent#ACTION_VIEW},
+ * category {@link android.content.Intent#CATEGORY_BROWSABLE}, scheme http or https, and which
+ * define a host can handle intents from the managed profile.
+ * The default value is <code>false</code>.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
+
+ /**
* Application restriction key that is used to indicate the pending arrival
* of real restrictions for the app.
*
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 8d11527..e33baa9 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -137,6 +137,7 @@
public final String id;
public final int type;
public final DiskInfo disk;
+ public final String partGuid;
public int mountFlags = 0;
public int mountUserId = -1;
public int state = STATE_UNMOUNTED;
@@ -149,10 +150,11 @@
/** Framework state */
public final int mtpIndex;
- public VolumeInfo(String id, int type, DiskInfo disk, int mtpIndex) {
+ public VolumeInfo(String id, int type, DiskInfo disk, String partGuid, int mtpIndex) {
this.id = Preconditions.checkNotNull(id);
this.type = type;
this.disk = disk;
+ this.partGuid = partGuid;
this.mtpIndex = mtpIndex;
}
@@ -164,6 +166,7 @@
} else {
disk = null;
}
+ partGuid = parcel.readString();
mountFlags = parcel.readInt();
mountUserId = parcel.readInt();
state = parcel.readInt();
@@ -385,6 +388,7 @@
pw.increaseIndent();
pw.printPair("type", DebugUtils.valueToString(getClass(), "TYPE_", type));
pw.printPair("diskId", getDiskId());
+ pw.printPair("partGuid", partGuid);
pw.printPair("mountFlags", DebugUtils.flagsToString(getClass(), "MOUNT_FLAG_", mountFlags));
pw.printPair("mountUserId", mountUserId);
pw.printPair("state", DebugUtils.valueToString(getClass(), "STATE_", state));
@@ -453,6 +457,7 @@
} else {
parcel.writeInt(0);
}
+ parcel.writeString(partGuid);
parcel.writeInt(mountFlags);
parcel.writeInt(mountUserId);
parcel.writeInt(state);
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
index 096e2dd..cb16305 100644
--- a/core/java/android/os/storage/VolumeRecord.java
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -39,6 +39,7 @@
public final int type;
public final String fsUuid;
+ public String partGuid;
public String nickname;
public int userFlags;
@@ -50,6 +51,7 @@
public VolumeRecord(Parcel parcel) {
type = parcel.readInt();
fsUuid = parcel.readString();
+ partGuid = parcel.readString();
nickname = parcel.readString();
userFlags = parcel.readInt();
}
@@ -79,6 +81,8 @@
pw.increaseIndent();
pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type));
pw.printPair("fsUuid", fsUuid);
+ pw.printPair("partGuid", partGuid);
+ pw.println();
pw.printPair("nickname", nickname);
pw.printPair("userFlags",
DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
@@ -133,6 +137,7 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(type);
parcel.writeString(fsUuid);
+ parcel.writeString(partGuid);
parcel.writeString(nickname);
parcel.writeInt(userFlags);
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index aebe7f1..8ce1cbf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1743,6 +1743,9 @@
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements StreamItemsColumns {
@@ -2831,6 +2834,9 @@
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
@@ -3267,6 +3273,9 @@
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
@@ -3365,6 +3374,9 @@
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItemPhotos
@@ -3415,6 +3427,9 @@
* @see ContactsContract.StreamItems
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
protected interface StreamItemsColumns {
@@ -3805,6 +3820,9 @@
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
@@ -3843,6 +3861,9 @@
* @see ContactsContract.StreamItemPhotos
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
protected interface StreamItemPhotosColumns {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 56cd1a7..9b5fbfa 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6685,6 +6685,17 @@
"wifi_mobile_data_transition_wakelock_timeout_ms";
/**
+ * This setting controls whether WiFi configurations created by a Device Owner app
+ * should be locked down (that is, be editable or removable only by the Device Owner App,
+ * not even by Settings app).
+ * This setting takes integer values. Non-zero values mean DO created configurations
+ * are locked down. Value of zero means they are not. Default value in the absence of
+ * actual value to this setting is 0.
+ */
+ public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
+ "wifi_device_owner_configs_lockdown";
+
+ /**
* The operational wifi frequency band
* Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
* {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 82f65c7..363376c 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -85,6 +85,12 @@
mArguments.add(new KeymasterDateArgument(tag, value));
}
+ public void addDateIfNotNull(int tag, Date value) {
+ if (value != null) {
+ mArguments.add(new KeymasterDateArgument(tag, value));
+ }
+ }
+
private KeymasterArgument getArgumentByTag(int tag) {
for (KeymasterArgument arg : mArguments) {
if (arg.tag == tag) {
diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index 225e70d..455e1b2 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -29,8 +29,8 @@
* <p>
* To extend this class, you must declare the service in your manifest file to require the
* {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
- * filter with the {@link #CONFIG_SERVICE_INTERFACE} action if the service exposes carrier config
- * and the {@link #BIND_SERVICE_INTERFACE} action if the service should have a long-lived binding.
+ * filter with the {@link #CARRIER_SERVICE_INTERFACE}. If the service should have a long-lived
+ * binding, set android.service.carrier.LONG_LIVED_BINDING to true in the service's metadata.
* For example:
* </p>
*
@@ -39,16 +39,16 @@
* android:label="@string/service_name"
* android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
- * <action android:name="android.service.carrier.ConfigService" />
- * <action android:name="android.service.carrier.BindService" />
+ * <action android:name="android.service.carrier.CarrierService" />
* </intent-filter>
+ * <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING"
+ * android:value="true" />
* </service>
* }</pre>
*/
public abstract class CarrierService extends Service {
- public static final String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService";
- public static final String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService";
+ public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
private static ITelephonyRegistry sRegistry;
@@ -127,13 +127,7 @@
@Override
@CallSuper
public IBinder onBind(Intent intent) {
- switch (intent.getAction()) {
- case CONFIG_SERVICE_INTERFACE:
- case BIND_SERVICE_INTERFACE:
- return mStubWrapper;
- default:
- return null;
- }
+ return mStubWrapper;
}
/**
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 39dd29b..f9e216a 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1146,20 +1146,7 @@
mContentFrame.requestApplyInsets();
}
- /** @hide */
- public void onHandleAssist(Bundle assistBundle) {
- }
-
public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
- if (data != null) {
- Bundle assistContext = data.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- assistContext.putParcelable(AssistStructure.ASSIST_KEY, structure);
- assistContext.putParcelable(AssistContent.ASSIST_KEY, content);
- data.putBundle(Intent.EXTRA_ASSIST_CONTEXT, assistContext);
- }
- }
- onHandleAssist(data);
}
public void onHandleScreenshot(Bitmap screenshot) {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index d51aa79..d8f7158 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -465,6 +465,11 @@
return false;
}
+ /** {@hide} */
+ public static String nullIfEmpty(@Nullable String str) {
+ return isEmpty(str) ? null : str;
+ }
+
/**
* Returns the length that the specified CharSequence would have if
* spaces and control characters were trimmed from the start and end,
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 13a959e..47d5c79 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -16,6 +16,7 @@
package android.text.format;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkUtils;
@@ -52,7 +53,10 @@
* @param sizeBytes size value to be formatted, in bytes
* @return formatted string with the number
*/
- public static String formatFileSize(Context context, long sizeBytes) {
+ public static String formatFileSize(@Nullable Context context, long sizeBytes) {
+ if (context == null) {
+ return "";
+ }
final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
return context.getString(com.android.internal.R.string.fileSizeSuffix,
res.value, res.units);
@@ -62,7 +66,10 @@
* Like {@link #formatFileSize}, but trying to generate shorter numbers
* (showing fewer digits of precision).
*/
- public static String formatShortFileSize(Context context, long sizeBytes) {
+ public static String formatShortFileSize(@Nullable Context context, long sizeBytes) {
+ if (context == null) {
+ return "";
+ }
final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
return context.getString(com.android.internal.R.string.fileSizeSuffix,
res.value, res.units);
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 8b74a1e..585fc4e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -504,13 +504,20 @@
private final boolean mIsForcedVisibility;
private final View mView;
private final int mFinalVisibility;
+ private final ViewGroup mParent;
+ private boolean mEnded;
boolean mCanceled = false;
public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) {
this.mView = view;
this.mIsForcedVisibility = isForcedVisibility;
this.mFinalVisibility = finalVisibility;
+ this.mParent = (ViewGroup) view.getParent();
+ if (!isForcedVisibility && mParent != null) {
+ // Prevent a layout from including mView in its calculation.
+ mParent.suppressLayout(true);
+ }
}
@Override
@@ -552,13 +559,39 @@
hideViewWhenNotCanceled();
}
+ @Override
+ public void onTransitionPause(Transition transition) {
+ if (mParent != null && !mIsForcedVisibility) {
+ mParent.suppressLayout(false);
+ }
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ if (mParent != null && !mIsForcedVisibility) {
+ mParent.suppressLayout(true);
+ }
+ }
+
private void hideViewWhenNotCanceled() {
- if (!mCanceled) {
- if (mIsForcedVisibility) {
- mView.setTransitionAlpha(0);
- } else {
- mView.setVisibility(mFinalVisibility);
+ if (!mEnded) {
+ if (!mCanceled) {
+ if (mIsForcedVisibility) {
+ mView.setTransitionAlpha(0);
+ } else {
+ // Recreate the parent's display list in case it includes mView.
+ mView.setTransitionVisibility(mFinalVisibility);
+ if (mParent != null) {
+ mParent.invalidate();
+ }
+ }
}
+ if (!mIsForcedVisibility && mParent != null) {
+ // Layout is allowed now that the View is in its final state
+ mParent.suppressLayout(false);
+ }
+ // Do this only once
+ mEnded = true;
}
}
}
diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java
index 211d01a..5524506 100644
--- a/core/java/android/util/Range.java
+++ b/core/java/android/util/Range.java
@@ -350,7 +350,7 @@
*/
@Override
public int hashCode() {
- return HashCodeHelpers.hashCode(mLower, mUpper);
+ return HashCodeHelpers.hashCodeGeneric(mLower, mUpper);
}
private final T mLower;
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 52a12f3..3c21981 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -323,10 +323,4 @@
}
private static native void nDrawRects(long renderer, long region, long paint);
-
- @Override
- public void drawPicture(Picture picture) {
- picture.endRecording();
- // TODO: Implement rendering
- }
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 4394cd8..6026d04 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1399,6 +1399,7 @@
private static native int nativeGetButtonState(long nativePtr);
private static native void nativeSetButtonState(long nativePtr, int buttonState);
private static native int nativeGetActionButton(long nativePtr);
+ private static native void nativeSetActionButton(long nativePtr, int actionButton);
private static native void nativeOffsetLocation(long nativePtr, float deltaX, float deltaY);
private static native float nativeGetXOffset(long nativePtr);
private static native float nativeGetYOffset(long nativePtr);
@@ -2284,6 +2285,16 @@
}
/**
+ * Sets the action button for the event.
+ *
+ * @see #getActionButton()
+ * @hide
+ */
+ public final void setActionButton(int button) {
+ nativeSetActionButton(mNativePtr, button);
+ }
+
+ /**
* Returns the original raw X coordinate of this event. For touch
* events on the screen, this is the original location of the event
* on the screen, before it had been adjusted for the containing window
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 4074529..5970c3f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -453,6 +453,19 @@
}
}
+ /**
+ * Sets the security of the surface. Setting the flag is equivalent to creating the
+ * Surface with the {@link #SECURE} flag.
+ */
+ public void setSecure(boolean isSecure) {
+ checkNotReleased();
+ if (isSecure) {
+ nativeSetFlags(mNativeObject, SECURE, SECURE);
+ } else {
+ nativeSetFlags(mNativeObject, 0, SECURE);
+ }
+ }
+
/*
* set display parameters.
* needs to be inside open/closeTransaction block
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fd3ee4f..502a6bc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6032,7 +6032,7 @@
public AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) {
- return provider.createAccessibilityNodeInfo(View.NO_ID);
+ return provider.createAccessibilityNodeInfo(AccessibilityNodeProvider.HOST_VIEW_ID);
} else {
AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
onInitializeAccessibilityNodeInfo(info);
@@ -6326,6 +6326,10 @@
* @hide
*/
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ if (mAttachInfo == null) {
+ return;
+ }
+
Rect bounds = mAttachInfo.mTmpInvalRect;
getDrawingRect(bounds);
@@ -8774,7 +8778,7 @@
* @hide
*/
public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
- if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
return;
}
if (mSendViewStateChangedAccessibilityEvent == null) {
@@ -8796,7 +8800,7 @@
* @hide
*/
public void notifySubtreeAccessibilityStateChangedIfNeeded() {
- if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
return;
}
if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
@@ -21037,6 +21041,9 @@
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
+ if (size < 0) {
+ throw new IllegalArgumentException("Measure spec size must be >= 0");
+ }
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index d06cd83..9ab0ace 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -150,7 +150,7 @@
* @param size The size, in pixels, of the text.
* @param fgColor The foreground color, packed as 0xAARRGGBB.
* @param bgColor The background color, packed as 0xAARRGGBB.
- * @param style Style flags, as defined by {@link android.app.AssistStructure.ViewNode}.
+ * @param style Style flags, as defined by {@link android.app.assist.AssistStructure.ViewNode}.
*/
public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);
@@ -221,7 +221,7 @@
* children at <var>index</var>.
* @return Returns an fresh {@link ViewStructure} ready to be filled in.
*/
- public abstract ViewAssistStructure newChild(int index);
+ public abstract ViewStructure newChild(int index);
/**
* Like {@link #newChild}, but allows the caller to asynchronously populate the returned
@@ -231,7 +231,7 @@
* population is done.
* @return Returns an fresh {@link ViewStructure} ready to be filled in.
*/
- public abstract ViewAssistStructure asyncNewChild(int index);
+ public abstract ViewStructure asyncNewChild(int index);
/**
* Call when done populating a {@link ViewStructure} returned by
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index ab793e0..87706ef 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -1115,7 +1115,7 @@
record.mParcelableData = parcel.readParcelable(null);
parcel.readList(record.mText, null);
record.mSourceWindowId = parcel.readInt();
- record.mSourceNodeId = parcel.readLong();
+ record.mSourceNode = parcel.readParcelable(null);
record.mSealed = (parcel.readInt() == 1);
}
@@ -1167,7 +1167,10 @@
parcel.writeParcelable(record.mParcelableData, flags);
parcel.writeList(record.mText);
parcel.writeInt(record.mSourceWindowId);
- parcel.writeLong(record.mSourceNodeId);
+ // create copy of the node here because the node would be recycled just after it is written
+ // to parcel
+ parcel.writeParcelable(record.mSourceNode != null ?
+ AccessibilityNodeInfo.obtain(record.mSourceNode) : null, flags);
parcel.writeInt(record.mSealed ? 1 : 0);
}
@@ -1191,7 +1194,9 @@
builder.append("\n");
builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
builder.append("; sourceWindowId: ").append(mSourceWindowId);
- builder.append("; mSourceNodeId: ").append(mSourceNodeId);
+ if (mSourceNode != null) {
+ builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId());
+ }
for (int i = 0; i < getRecordCount(); i++) {
final AccessibilityRecord record = getRecord(i);
builder.append(" Record ");
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 36de8f3..86ed499 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -2821,7 +2821,7 @@
* @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
*/
private void initFromParcel(Parcel parcel) {
- mSealed = (parcel.readInt() == 1);
+ final boolean sealed = (parcel.readInt() == 1);
mSourceNodeId = parcel.readLong();
mWindowId = parcel.readInt();
mParentNodeId = parcel.readLong();
@@ -2911,6 +2911,8 @@
parcel.readInt() == 1,
parcel.readInt() == 1);
}
+
+ mSealed = sealed;
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index cc6a71d..f99690a 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -90,7 +90,7 @@
int mAddedCount= UNDEFINED;
int mRemovedCount = UNDEFINED;
- long mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+ AccessibilityNodeInfo mSourceNode;
int mSourceWindowId = UNDEFINED;
CharSequence mClassName;
@@ -135,16 +135,24 @@
*/
public void setSource(View root, int virtualDescendantId) {
enforceNotSealed();
- final boolean important;
- if (virtualDescendantId == UNDEFINED) {
- important = (root != null) ? root.isImportantForAccessibility() : true;
- } else {
- important = true;
+ boolean important = true;
+ mSourceWindowId = UNDEFINED;
+ clearSourceNode();
+ if (root != null) {
+ if (virtualDescendantId == UNDEFINED ||
+ virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ important = root.isImportantForAccessibility();
+ mSourceNode = root.createAccessibilityNodeInfo();
+ } else {
+ AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
+ if (provider != null) {
+ mSourceNode = provider.createAccessibilityNodeInfo(virtualDescendantId);
+ }
+ }
+
+ mSourceWindowId = root.getAccessibilityWindowId();
}
setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
- mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
- final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
- mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
}
/**
@@ -158,13 +166,11 @@
*/
public AccessibilityNodeInfo getSource() {
enforceSealed();
- if (mConnectionId == UNDEFINED || mSourceWindowId == UNDEFINED
- || AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId) == UNDEFINED) {
- return null;
+ if (mSourceNode != null) {
+ return AccessibilityNodeInfo.obtain(mSourceNode);
}
- AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
- mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS);
+
+ return null;
}
/**
@@ -619,7 +625,7 @@
* @hide
*/
public long getSourceNodeId() {
- return mSourceNodeId;
+ return mSourceNode != null ? mSourceNode.getSourceNodeId() : UNDEFINED;
}
/**
@@ -633,6 +639,9 @@
public void setConnectionId(int connectionId) {
enforceNotSealed();
mConnectionId = connectionId;
+ if (mSourceNode != null) {
+ mSourceNode.setConnectionId(mConnectionId);
+ }
}
/**
@@ -644,6 +653,9 @@
*/
public void setSealed(boolean sealed) {
mSealed = sealed;
+ if (mSourceNode != null) {
+ mSourceNode.setSealed(sealed);
+ }
}
/**
@@ -782,7 +794,9 @@
mParcelableData = record.mParcelableData;
mText.addAll(record.mText);
mSourceWindowId = record.mSourceWindowId;
- mSourceNodeId = record.mSourceNodeId;
+ if (record.mSourceNode != null) {
+ mSourceNode = AccessibilityNodeInfo.obtain(record.mSourceNode);
+ }
mConnectionId = record.mConnectionId;
}
@@ -807,11 +821,18 @@
mBeforeText = null;
mParcelableData = null;
mText.clear();
- mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+ clearSourceNode();
mSourceWindowId = UNDEFINED;
mConnectionId = UNDEFINED;
}
+ private void clearSourceNode() {
+ if (mSourceNode != null) {
+ mSourceNode.recycle();
+ mSourceNode = null;
+ }
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index 410d39c..14f0b0a 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -266,11 +266,19 @@
* background colors, edge properties, and typeface.
*/
public static final class CaptionStyle {
- /** Packed value for a color of 'none' and a cached opacity of 100%. */
+ /**
+ * Packed value for a color of 'none' and a cached opacity of 100%.
+ *
+ * @hide
+ */
private static final int COLOR_NONE_OPAQUE = 0x000000FF;
- /** Packed value for an unspecified color and opacity. */
- private static final int COLOR_UNSPECIFIED = 0x000001FF;
+ /**
+ * Packed value for a color of 'default' and opacity of 100%.
+ *
+ * @hide
+ */
+ public static final int COLOR_UNSPECIFIED = 0x00FFFFFF;
private static final CaptionStyle WHITE_ON_BLACK;
private static final CaptionStyle BLACK_ON_WHITE;
@@ -350,11 +358,11 @@
private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
int windowColor, String rawTypeface) {
- mHasForegroundColor = foregroundColor != COLOR_UNSPECIFIED;
- mHasBackgroundColor = backgroundColor != COLOR_UNSPECIFIED;
+ mHasForegroundColor = hasColor(foregroundColor);
+ mHasBackgroundColor = hasColor(backgroundColor);
mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED;
- mHasEdgeColor = edgeColor != COLOR_UNSPECIFIED;
- mHasWindowColor = windowColor != COLOR_UNSPECIFIED;
+ mHasEdgeColor = hasColor(edgeColor);
+ mHasWindowColor = hasColor(windowColor);
// Always use valid colors, even when no override is specified, to
// ensure backwards compatibility with apps targeting KitKat MR2.
@@ -368,6 +376,20 @@
}
/**
+ * Returns whether a packed color indicates a non-default value.
+ *
+ * @param packedColor the packed color value
+ * @return {@code true} if a non-default value is specified
+ * @hide
+ */
+ public static boolean hasColor(int packedColor) {
+ // Matches the color packing code from Settings. "Default" packed
+ // colors are indicated by zero alpha and non-zero red/blue. The
+ // cached alpha value used by Settings is stored in green.
+ return (packedColor >>> 24) != 0 || (packedColor & 0xFFFF00) == 0;
+ }
+
+ /**
* Applies a caption style, overriding any properties that are specified
* in the overlay caption.
*
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 2f5c9e2..de8ccc1 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -298,14 +298,27 @@
* Notify the host application to handle a SSL client certificate
* request. The host application is responsible for showing the UI
* if desired and providing the keys. There are three ways to
- * respond: proceed(), cancel() or ignore(). Webview remembers the
- * response if proceed() or cancel() is called and does not
- * call onReceivedClientCertRequest() again for the same host and port
- * pair. Webview does not remember the response if ignore() is called.
+ * respond: proceed(), cancel() or ignore(). Webview stores the response
+ * in memory (for the life of the application) if proceed() or cancel() is
+ * called and does not call onReceivedClientCertRequest() again for the
+ * same host and port pair. Webview does not store the response if ignore()
+ * is called.
*
* This method is called on the UI thread. During the callback, the
* connection is suspended.
*
+ * For most use cases, the application program should implement the
+ * {@link android.security.KeyChainAliasCallback} interface and pass it to
+ * {@link android.security.KeyChain#choosePrivateKeyAlias} to start an
+ * activity for the user to choose the proper alias. The keychain activity will
+ * provide the alias through the callback method in the implemented interface. Next
+ * the application should create an async task to call
+ * {@link android.security.KeyChain#getPrivateKey} to receive the key.
+ *
+ * An example implementation of client certificates can be seen at
+ * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java">
+ * AOSP Browser</a>
+ *
* The default behavior is to cancel, returning no client certificate.
*
* @param view The WebView that is initiating the callback
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index affc5da..339038e 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@
View baselineView = null;
LayoutParams baselineParams = null;
for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@
if (offsetHorizontalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
centerHorizontal(child, params, width);
@@ -578,9 +578,9 @@
if (offsetVerticalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
centerVertical(child, params, height);
@@ -607,9 +607,9 @@
final int verticalOffset = contentBounds.top - top;
if (horizontalOffset != 0 || verticalOffset != 0) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE && child != ignore) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (horizontalGravity) {
params.mLeft += horizontalOffset;
params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@
if (isLayoutRtl()) {
final int offsetWidth = myWidth - width;
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mLeft -= offsetWidth;
params.mRight -= offsetWidth;
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index fdabe91..6abd1293 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -711,9 +711,7 @@
lp = generateDefaultLayoutParams();
}
- if (addChild) {
- addViewInLayout(child, 0, lp);
- }
+ addViewInLayout(child, 0, lp);
child.setSelected(hasFocus());
if (mDisableChildrenWhenDisabled) {
@@ -743,6 +741,10 @@
childRight = childLeft + width;
child.layout(childLeft, childTop, childRight, childBottom);
+
+ if (!addChild) {
+ removeViewInLayout(child);
+ }
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f733eab..e84ba99 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -25,7 +25,7 @@
import android.annotation.StyleRes;
import android.annotation.XmlRes;
import android.app.Activity;
-import android.app.AssistStructure;
+import android.app.assist.AssistStructure;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -9443,10 +9443,12 @@
public void onRtlPropertiesChanged(int layoutDirection) {
super.onRtlPropertiesChanged(layoutDirection);
- mTextDir = getTextDirectionHeuristic();
-
- if (mLayout != null) {
- checkForRelayout();
+ final TextDirectionHeuristic newTextDir = getTextDirectionHeuristic();
+ if (mTextDir != newTextDir) {
+ mTextDir = newTextDir;
+ if (mLayout != null) {
+ checkForRelayout();
+ }
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 678e92b..1b55557 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -100,6 +100,10 @@
mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets);
unbindService(sri.connection);
mServiceConnections.remove(sri.connection);
+ if (mServiceConnections.isEmpty()) {
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
+ sendVoiceChoicesIfNeeded();
+ }
break;
case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT:
@@ -107,6 +111,7 @@
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
unbindRemainingServices();
+ sendVoiceChoicesIfNeeded();
break;
default:
@@ -384,6 +389,8 @@
+ WATCHDOG_TIMEOUT_MILLIS + "ms");
mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
WATCHDOG_TIMEOUT_MILLIS);
+ } else {
+ sendVoiceChoicesIfNeeded();
}
}
@@ -418,6 +425,10 @@
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
}
+ void onSetupVoiceInteraction() {
+ // Do nothing. We'll send the voice stuff ourselves.
+ }
+
void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) {
if (mRefinementResultReceiver != null) {
mRefinementResultReceiver.destroy();
@@ -956,6 +967,10 @@
if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name);
unbindService(this);
mServiceConnections.remove(this);
+ if (mServiceConnections.isEmpty()) {
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
+ sendVoiceChoicesIfNeeded();
+ }
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index e14f058..fe3ab9e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,10 +16,17 @@
package com.android.internal.app;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.PickOptionRequest;
+import android.app.VoiceInteractor.PickOptionRequest.Option;
+import android.app.VoiceInteractor.Prompt;
+import android.app.VoiceInteractor.Request;
import android.os.AsyncTask;
import android.provider.Settings;
+import android.service.chooser.ChooserTarget;
import android.text.TextUtils;
import android.util.Slog;
import android.widget.AbsListView;
@@ -96,6 +103,7 @@
private int mProfileSwitchMessageId = -1;
private final ArrayList<Intent> mIntents = new ArrayList<>();
private ResolverComparator mResolverComparator;
+ private PickTargetOptionRequest mPickOptionRequest;
private boolean mRegistered;
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@@ -242,6 +250,9 @@
finish();
}
});
+ if (isVoiceInteraction()) {
+ rdl.setCollapsed(false);
+ }
}
if (title == null) {
@@ -313,6 +324,39 @@
});
bindProfileView();
}
+
+ if (isVoiceInteraction()) {
+ onSetupVoiceInteraction();
+ }
+ }
+
+ /**
+ * Perform any initialization needed for voice interaction.
+ */
+ void onSetupVoiceInteraction() {
+ // Do it right now. Subclasses may delay this and send it later.
+ sendVoiceChoicesIfNeeded();
+ }
+
+ void sendVoiceChoicesIfNeeded() {
+ if (!isVoiceInteraction()) {
+ // Clearly not needed.
+ return;
+ }
+
+
+ final Option[] options = new Option[mAdapter.getCount()];
+ for (int i = 0, N = options.length; i < N; i++) {
+ options[i] = optionForChooserTarget(mAdapter.getItem(i), i);
+ }
+
+ mPickOptionRequest = new PickTargetOptionRequest(
+ new Prompt(getTitle()), options, null);
+ getVoiceInteractor().submitRequest(mPickOptionRequest);
+ }
+
+ Option optionForChooserTarget(TargetInfo target, int index) {
+ return new Option(target.getDisplayLabel(), index);
}
protected final void setAdditionalTargets(Intent[] intents) {
@@ -473,6 +517,14 @@
}
@Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (!isChangingConfigurations() && mPickOptionRequest != null) {
+ mPickOptionRequest.cancel();
+ }
+ }
+
+ @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (mAlwaysUseOption) {
@@ -510,16 +562,12 @@
try {
ApplicationInfo appInfo = getPackageManager().getApplicationInfo(
resolveInfo.activityInfo.packageName, 0 /* default flags */);
- return versionNumberAtLeastL(appInfo.targetSdkVersion);
+ return appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP;
} catch (NameNotFoundException e) {
return false;
}
}
- private boolean versionNumberAtLeastL(int versionNumber) {
- return versionNumber >= Build.VERSION_CODES.LOLLIPOP;
- }
-
private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos,
boolean filtered) {
boolean enabled = false;
@@ -1644,4 +1692,39 @@
&& match <= IntentFilter.MATCH_CATEGORY_PATH;
}
+ static class PickTargetOptionRequest extends PickOptionRequest {
+ public PickTargetOptionRequest(@Nullable Prompt prompt, Option[] options,
+ @Nullable Bundle extras) {
+ super(prompt, options, extras);
+ }
+
+ @Override
+ public void onCancel() {
+ super.onCancel();
+ final ResolverActivity ra = (ResolverActivity) getActivity();
+ if (ra != null) {
+ ra.mPickOptionRequest = null;
+ ra.finish();
+ }
+ }
+
+ @Override
+ public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+ super.onPickOptionResult(finished, selections, result);
+ if (selections.length != 1) {
+ // TODO In a better world we would filter the UI presented here and let the
+ // user refine. Maybe later.
+ return;
+ }
+
+ final ResolverActivity ra = (ResolverActivity) getActivity();
+ if (ra != null) {
+ final TargetInfo ti = ra.mAdapter.getItem(selections[0].getIndex());
+ if (ra.onTargetSelected(ti, false)) {
+ ra.mPickOptionRequest = null;
+ ra.finish();
+ }
+ }
+ }
+ }
}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 042db71..ac17cbe 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -22,9 +22,10 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
@@ -646,7 +647,8 @@
}
public static void setNonSelectedSystemImesDisabledUntilUsed(
- PackageManager packageManager, List<InputMethodInfo> enabledImis) {
+ IPackageManager packageManager, List<InputMethodInfo> enabledImis,
+ int userId, String callingPackage) {
if (DEBUG) {
Slog.d(TAG, "setNonSelectedSystemImesDisabledUntilUsed");
}
@@ -685,9 +687,11 @@
ApplicationInfo ai = null;
try {
ai = packageManager.getApplicationInfo(packageName,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
- } catch (NameNotFoundException e) {
- Slog.w(TAG, "NameNotFoundException: " + packageName, e);
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getApplicationInfo failed. packageName=" + packageName
+ + " userId=" + userId, e);
+ continue;
}
if (ai == null) {
// No app found for packageName
@@ -697,19 +701,34 @@
if (!isSystemPackage) {
continue;
}
- setDisabledUntilUsed(packageManager, packageName);
+ setDisabledUntilUsed(packageManager, packageName, userId, callingPackage);
}
}
- private static void setDisabledUntilUsed(PackageManager packageManager, String packageName) {
- final int state = packageManager.getApplicationEnabledSetting(packageName);
+ private static void setDisabledUntilUsed(IPackageManager packageManager, String packageName,
+ int userId, String callingPackage) {
+ final int state;
+ try {
+ state = packageManager.getApplicationEnabledSetting(packageName, userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getApplicationEnabledSetting failed. packageName=" + packageName
+ + " userId=" + userId, e);
+ return;
+ }
if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
if (DEBUG) {
Slog.d(TAG, "Update state(" + packageName + "): DISABLED_UNTIL_USED");
}
- packageManager.setApplicationEnabledSetting(packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0);
+ try {
+ packageManager.setApplicationEnabledSetting(packageName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
+ 0 /* newState */, userId, callingPackage);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "setApplicationEnabledSetting failed. packageName=" + packageName
+ + " userId=" + userId + " callingPackage=" + callingPackage, e);
+ return;
+ }
} else {
if (DEBUG) {
Slog.d(TAG, packageName + " is already DISABLED_UNTIL_USED");
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index e4ccb4b..b78eca7 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -37,6 +37,9 @@
public static final int ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
public static final int ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
public static final int ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
+ public static final int ACTION_BRIGHTNESS = 218;
+ public static final int ACTION_BRIGHTNESS_AUTO = 219;
+ public static final int BRIGHTNESS_DIALOG = 220;
// Temporary constants go here, to await migration to MetricsConstants.
public static void visible(Context context, int category) throws IllegalArgumentException {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 83ce5f6..1bd821d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -208,7 +208,7 @@
final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
- final ArrayList<StopwatchTimer> mDozeTimers = new ArrayList<>();
+ final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
@@ -5649,9 +5649,9 @@
StopwatchTimer mTimerWindow;
/**
- * How long (in ms) this uid has had a doze wake lock.
+ * How long (in ms) this uid has had a draw wake lock.
*/
- StopwatchTimer mTimerDoze;
+ StopwatchTimer mTimerDraw;
/**
* Reads a possibly null Timer from a Parcel. The timer is associated with the
@@ -5680,8 +5680,8 @@
if (mTimerWindow != null) {
wlactive |= !mTimerWindow.reset(false);
}
- if (mTimerDoze != null) {
- wlactive |= !mTimerDoze.reset(false);
+ if (mTimerDraw != null) {
+ wlactive |= !mTimerDraw.reset(false);
}
if (!wlactive) {
if (mTimerFull != null) {
@@ -5696,9 +5696,9 @@
mTimerWindow.detach();
mTimerWindow = null;
}
- if (mTimerDoze != null) {
- mTimerDoze.detach();
- mTimerDoze = null;
+ if (mTimerDraw != null) {
+ mTimerDraw.detach();
+ mTimerDraw = null;
}
}
return !wlactive;
@@ -5709,14 +5709,14 @@
mPartialTimers, screenOffTimeBase, in);
mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, mFullTimers, timeBase, in);
mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, mWindowTimers, timeBase, in);
- mTimerDoze = readTimerFromParcel(WAKE_TYPE_DOZE, mDozeTimers, timeBase, in);
+ mTimerDraw = readTimerFromParcel(WAKE_TYPE_DRAW, mDrawTimers, timeBase, in);
}
void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
- Timer.writeTimerToParcel(out, mTimerDoze, elapsedRealtimeUs);
+ Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs);
}
@Override
@@ -5725,7 +5725,7 @@
case WAKE_TYPE_FULL: return mTimerFull;
case WAKE_TYPE_PARTIAL: return mTimerPartial;
case WAKE_TYPE_WINDOW: return mTimerWindow;
- case WAKE_TYPE_DOZE: return mTimerDoze;
+ case WAKE_TYPE_DRAW: return mTimerDraw;
default: throw new IllegalArgumentException("type = " + type);
}
}
@@ -5757,13 +5757,14 @@
mTimerWindow = t;
}
return t;
- case WAKE_TYPE_DOZE:
- t = mTimerDoze;
+ case WAKE_TYPE_DRAW:
+ t = mTimerDraw;
if (t == null) {
- t = new StopwatchTimer(Uid.this, WAKE_TYPE_DOZE,
- mDozeTimers, mOnBatteryTimeBase);
- mTimerDoze = t;
+ t = new StopwatchTimer(Uid.this, WAKE_TYPE_DRAW,
+ mDrawTimers, mOnBatteryTimeBase);
+ mTimerDraw = t;
}
+ return t;
default:
throw new IllegalArgumentException("type=" + type);
}
@@ -6621,7 +6622,7 @@
wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
- wl.getStopwatchTimer(WAKE_TYPE_DOZE).readSummaryFromParcelLocked(in);
+ wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
}
}
@@ -9610,9 +9611,9 @@
} else {
out.writeInt(0);
}
- if (wl.mTimerDoze != null) {
+ if (wl.mTimerDraw != null) {
out.writeInt(1);
- wl.mTimerDoze.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
} else {
out.writeInt(0);
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 15ed5bd..0abd200 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -23,6 +23,8 @@
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.*;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
import android.app.ActivityManagerNative;
import android.app.SearchManager;
import android.os.UserHandle;
@@ -2216,6 +2218,7 @@
private OnPreDrawListener mFloatingToolbarPreDrawListener;
private View mFloatingActionModeOriginatingView;
private FloatingToolbar mFloatingToolbar;
+ private ObjectAnimator mFadeAnim;
// View added at runtime to draw under the status bar area
private View mStatusGuard;
@@ -3345,6 +3348,7 @@
}
private ActionMode createStandaloneActionMode(ActionMode.Callback callback) {
+ endOnGoingFadeAnimation();
cleanupPrimaryActionMode();
if (mPrimaryActionModeView == null) {
if (isFloating()) {
@@ -3384,6 +3388,32 @@
mPrimaryActionModePopup.showAtLocation(
mPrimaryActionModeView.getApplicationWindowToken(),
Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
+ endOnGoingFadeAnimation();
+ mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
+ 0f, 1f);
+ mFadeAnim.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mPrimaryActionModeView.setVisibility(VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPrimaryActionModeView.setAlpha(1f);
+ mFadeAnim = null;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ });
+ mFadeAnim.start();
}
};
} else {
@@ -3404,13 +3434,44 @@
return null;
}
+ private void endOnGoingFadeAnimation() {
+ if (mFadeAnim != null) {
+ mFadeAnim.end();
+ }
+ }
+
private void setHandledPrimaryActionMode(ActionMode mode) {
+ endOnGoingFadeAnimation();
mPrimaryActionMode = mode;
mPrimaryActionMode.invalidate();
mPrimaryActionModeView.initForMode(mPrimaryActionMode);
- mPrimaryActionModeView.setVisibility(View.VISIBLE);
if (mPrimaryActionModePopup != null) {
post(mShowPrimaryActionModePopup);
+ } else {
+ mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f);
+ mFadeAnim.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mPrimaryActionModeView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPrimaryActionModeView.setAlpha(1f);
+ mFadeAnim = null;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ });
+ mFadeAnim.start();
}
mPrimaryActionModeView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
@@ -3473,13 +3534,40 @@
if (mode == mPrimaryActionMode) {
if (mPrimaryActionModePopup != null) {
removeCallbacks(mShowPrimaryActionModePopup);
- mPrimaryActionModePopup.dismiss();
- } else if (mPrimaryActionModeView != null) {
- mPrimaryActionModeView.setVisibility(GONE);
}
if (mPrimaryActionModeView != null) {
- mPrimaryActionModeView.removeAllViews();
+ endOnGoingFadeAnimation();
+ mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
+ 1f, 0f);
+ mFadeAnim.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPrimaryActionModeView.setVisibility(GONE);
+ if (mPrimaryActionModePopup != null) {
+ mPrimaryActionModePopup.dismiss();
+ }
+ mPrimaryActionModeView.removeAllViews();
+ mFadeAnim = null;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ });
+ mFadeAnim.start();
}
+
mPrimaryActionMode = null;
} else if (mode == mFloatingActionMode) {
cleanupFloatingActionModeViews();
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 663c838..aea1585 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -19,6 +19,7 @@
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.NotificationVisibility;
import android.service.notification.StatusBarNotification;
/** @hide */
@@ -53,8 +54,8 @@
int uid, int initialPid, String message, int userId);
void onClearAllNotifications(int userId);
void onNotificationClear(String pkg, String tag, int id, int userId);
- void onNotificationVisibilityChanged(
- in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys);
+ void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys,
+ in NotificationVisibility[] noLongerVisibleKeys);
void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded);
void setSystemUiVisibility(int vis, int mask, String cause);
void setWindowState(int window, int state);
diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/com/android/internal/statusbar/NotificationVisibility.aidl
similarity index 64%
copy from core/java/android/view/ViewAssistStructure.java
copy to core/java/com/android/internal/statusbar/NotificationVisibility.aidl
index a66d93c..c067551 100644
--- a/core/java/android/view/ViewAssistStructure.java
+++ b/core/java/com/android/internal/statusbar/NotificationVisibility.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,7 @@
* limitations under the License.
*/
-package android.view;
+package com.android.internal.statusbar;
-/**
- * @deprecated Temporary until old apps can move off this.
- */
-@Deprecated
-public abstract class ViewAssistStructure extends ViewStructure {
-}
+parcelable NotificationVisibility;
+
diff --git a/core/java/com/android/internal/statusbar/NotificationVisibility.java b/core/java/com/android/internal/statusbar/NotificationVisibility.java
new file mode 100644
index 0000000..2139ad0
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/NotificationVisibility.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.statusbar;
+
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+
+public class NotificationVisibility implements Parcelable {
+ private static final String TAG = "NoViz";
+ private static final int MAX_POOL_SIZE = 25;
+ private static ArrayDeque<NotificationVisibility> sPool = new ArrayDeque<>(MAX_POOL_SIZE);
+ private static int sNexrId = 0;
+
+ public String key;
+ public int rank;
+ public boolean visible = true;
+ /*package*/ int id;
+
+ private NotificationVisibility() {
+ id = sNexrId++;
+ }
+
+ private NotificationVisibility(String key, int rank, boolean visibile) {
+ this();
+ this.key = key;
+ this.rank = rank;
+ this.visible = visibile;
+ }
+
+ @Override
+ public String toString() {
+ return "NotificationVisibility(id=" + id
+ + "key=" + key
+ + " rank=" + rank
+ + (visible?" visible":"")
+ + " )";
+ }
+
+ @Override
+ public NotificationVisibility clone() {
+ return obtain(this.key, this.rank, this.visible);
+ }
+
+ @Override
+ public int hashCode() {
+ // allow lookups by key, which _should_ never be null.
+ return key == null ? 0 : key.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ // allow lookups by key, which _should_ never be null.
+ if (that instanceof NotificationVisibility) {
+ NotificationVisibility thatViz = (NotificationVisibility) that;
+ return (key == null && thatViz.key == null) || key.equals(thatViz.key);
+ }
+ return false;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(this.key);
+ out.writeInt(this.rank);
+ out.writeInt(this.visible ? 1 : 0);
+ }
+
+ private void readFromParcel(Parcel in) {
+ this.key = in.readString();
+ this.rank = in.readInt();
+ this.visible = in.readInt() != 0;
+ }
+
+ /**
+ * Return a new NotificationVisibility instance from the global pool. Allows us to
+ * avoid allocating new objects in many cases.
+ */
+ public static NotificationVisibility obtain(String key, int rank, boolean visible) {
+ NotificationVisibility vo = obtain();
+ vo.key = key;
+ vo.rank = rank;
+ vo.visible = visible;
+ return vo;
+ }
+
+ private static NotificationVisibility obtain(Parcel in) {
+ NotificationVisibility vo = obtain();
+ vo.readFromParcel(in);
+ return vo;
+ }
+
+ private static NotificationVisibility obtain() {
+ synchronized (sPool) {
+ if (!sPool.isEmpty()) {
+ return sPool.poll();
+ }
+ }
+ return new NotificationVisibility();
+ }
+
+ /**
+ * Return a NotificationVisibility instance to the global pool.
+ * <p>
+ * You MUST NOT touch the NotificationVisibility after calling this function because it has
+ * effectively been freed.
+ * </p>
+ */
+ public void recycle() {
+ if (key == null) {
+ // do nothing on multiple recycles
+ return;
+ }
+ key = null;
+ if (sPool.size() < MAX_POOL_SIZE) {
+ synchronized (sPool) {
+ sPool.offer(this);
+ }
+ }
+ }
+
+ /**
+ * Parcelable.Creator that instantiates NotificationVisibility objects
+ */
+ public static final Parcelable.Creator<NotificationVisibility> CREATOR
+ = new Parcelable.Creator<NotificationVisibility>()
+ {
+ public NotificationVisibility createFromParcel(Parcel parcel)
+ {
+ return obtain(parcel);
+ }
+
+ public NotificationVisibility[] newArray(int size)
+ {
+ return new NotificationVisibility[size];
+ }
+ };
+}
+
diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java
index 39613e8..3b7bce4 100644
--- a/core/java/com/android/internal/widget/ButtonBarLayout.java
+++ b/core/java/com/android/internal/widget/ButtonBarLayout.java
@@ -31,7 +31,7 @@
*/
public class ButtonBarLayout extends LinearLayout {
/** Whether the current configuration allows stacking. */
- private final boolean mAllowStacking;
+ private boolean mAllowStacking;
private int mLastWidthSize = -1;
@@ -43,6 +43,16 @@
ta.recycle();
}
+ public void setAllowStacking(boolean allowStacking) {
+ if (mAllowStacking != allowStacking) {
+ mAllowStacking = allowStacking;
+ if (!mAllowStacking && getOrientation() == LinearLayout.VERTICAL) {
+ setStacked(false);
+ }
+ requestLayout();
+ }
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 585cbc9..1071e12 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -144,6 +144,14 @@
return mCollapseOffset > 0;
}
+ public void setCollapsed(boolean collapsed) {
+ if (!isLaidOut()) {
+ mOpenOnLayout = collapsed;
+ } else {
+ smoothScrollTo(collapsed ? mCollapsibleHeight : 0, 0);
+ }
+ }
+
private boolean isMoving() {
return mIsDragging || !mScroller.isFinished();
}
@@ -575,7 +583,13 @@
@Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) {
- smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
+ if (mOnDismissedListener != null
+ && velocityY < 0 && mCollapseOffset > mCollapsibleHeight) {
+ smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY);
+ mDismissOnScrollerFinished = true;
+ } else {
+ smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
+ }
return true;
}
return false;
diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
index 26f5bf4..458a2ca 100644
--- a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
+++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
@@ -27,48 +27,69 @@
private static final boolean DEBUG = false;
// current schema of the backup state blob
- private static final int STATE_VERSION = 2;
+ private static final int STATE_VERSION = 3;
// key under which the preferred-activity state blob is committed to backup
private static final String KEY_PREFERRED = "preferred-activity";
+ // key for default-browser [etc] state
+ private static final String KEY_DEFAULT_APPS = "default-apps";
+
+ // intent-filter verification state
+ private static final String KEY_INTENT_VERIFICATION = "intent-verification";
+
public PreferredActivityBackupHelper() {
- super(STATE_VERSION, KEY_PREFERRED);
+ super(STATE_VERSION,
+ KEY_PREFERRED,
+ KEY_DEFAULT_APPS,
+ KEY_INTENT_VERIFICATION);
}
@Override
protected byte[] getBackupPayload(String key) {
- if (KEY_PREFERRED.equals(key)) {
- if (DEBUG) {
- Slog.v(TAG, "Checking whether to back up");
+ IPackageManager pm = AppGlobals.getPackageManager();
+ if (DEBUG) {
+ Slog.d(TAG, "Handling backup of " + key);
+ }
+ try {
+ switch (key) {
+ case KEY_PREFERRED:
+ return pm.getPreferredActivityBackup(UserHandle.USER_OWNER);
+ case KEY_DEFAULT_APPS:
+ return pm.getDefaultAppsBackup(UserHandle.USER_OWNER);
+ case KEY_INTENT_VERIFICATION:
+ return pm.getIntentFilterVerificationBackup(UserHandle.USER_OWNER);
+ default:
+ Slog.w(TAG, "Unexpected backup key " + key);
}
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- return pm.getPreferredActivityBackup(UserHandle.USER_OWNER);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to store backup payload", e);
- // fall through to report null state
- }
- } else {
- Slog.w(TAG, "Unexpected backup key " + key);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to store payload " + key);
}
return null;
}
@Override
protected void applyRestoredPayload(String key, byte[] payload) {
- if (KEY_PREFERRED.equals(key)) {
- if (DEBUG) {
- Slog.v(TAG, "Restoring");
+ IPackageManager pm = AppGlobals.getPackageManager();
+ if (DEBUG) {
+ Slog.d(TAG, "Handling restore of " + key);
+ }
+ try {
+ switch (key) {
+ case KEY_PREFERRED:
+ pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
+ break;
+ case KEY_DEFAULT_APPS:
+ pm.restoreDefaultApps(payload, UserHandle.USER_OWNER);
+ break;
+ case KEY_INTENT_VERIFICATION:
+ pm.restoreIntentFilterVerification(payload, UserHandle.USER_OWNER);
+ break;
+ default:
+ Slog.w(TAG, "Unexpected restore key " + key);
}
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to restore", e);
- }
- } else {
- Slog.w(TAG, "Unexpected restore key " + key);
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to restore key " + key);
}
}
}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 9b5fb3a..2116da0 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -175,24 +175,24 @@
static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t,
jfloat r, jfloat b, jint opHandle) {
SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
- bool emptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op);
- return emptyClip ? JNI_FALSE : JNI_TRUE;
+ bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op);
+ return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}
static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
jint opHandle) {
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
- bool emptyClip = get_canvas(canvasHandle)->clipPath(path, op);
- return emptyClip ? JNI_FALSE : JNI_TRUE;
+ bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, op);
+ return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}
static jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle,
jint opHandle) {
SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
- bool emptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op);
- return emptyClip ? JNI_FALSE : JNI_TRUE;
+ bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op);
+ return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}
static void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) {
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index f5f8b1f..c9d609c 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -257,6 +257,8 @@
case SENSOR_TYPE_MAGNETIC_FIELD:
case SENSOR_TYPE_ACCELEROMETER:
case SENSOR_TYPE_GYROSCOPE:
+ case SENSOR_TYPE_GRAVITY:
+ case SENSOR_TYPE_LINEAR_ACCELERATION:
status = buffer[i].vector.status;
break;
case SENSOR_TYPE_HEART_RATE:
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 7d8d151..995d39f 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "DngCreator_JNI"
#include <inttypes.h>
#include <string.h>
+#include <algorithm>
+#include <memory>
#include <utils/Log.h>
#include <utils/Errors.h>
@@ -25,7 +27,6 @@
#include <utils/RefBase.h>
#include <utils/Vector.h>
#include <cutils/properties.h>
-
#include <system/camera_metadata.h>
#include <camera/CameraMetadata.h>
#include <img_utils/DngUtils.h>
@@ -37,15 +38,6 @@
#include <img_utils/StripSource.h>
#include "core_jni_helpers.h"
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/StrongPointer.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-#include <cutils/properties.h>
-
-#include <string.h>
-#include <inttypes.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/android_hardware_camera2_CameraMetadata.h"
@@ -63,6 +55,14 @@
return; \
}
+#define BAIL_IF_INVALID_R(expr, jnienv, tagId, writer) \
+ if ((expr) != OK) { \
+ jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \
+ "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \
+ return -1; \
+ }
+
+
#define BAIL_IF_EMPTY(entry, jnienv, tagId, writer) \
if (entry.count == 0) { \
jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \
@@ -111,11 +111,14 @@
class NativeContext : public LightRefBase<NativeContext> {
public:
- NativeContext();
+ NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result);
virtual ~NativeContext();
TiffWriter* getWriter();
+ std::shared_ptr<const CameraMetadata> getCharacteristics() const;
+ std::shared_ptr<const CameraMetadata> getResult() const;
+
uint32_t getThumbnailWidth();
uint32_t getThumbnailHeight();
const uint8_t* getThumbnail();
@@ -125,11 +128,16 @@
private:
Vector<uint8_t> mCurrentThumbnail;
TiffWriter mWriter;
+ std::shared_ptr<CameraMetadata> mCharacteristics;
+ std::shared_ptr<CameraMetadata> mResult;
uint32_t mThumbnailWidth;
uint32_t mThumbnailHeight;
};
-NativeContext::NativeContext() : mThumbnailWidth(0), mThumbnailHeight(0) {}
+NativeContext::NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result) :
+ mCharacteristics(std::make_shared<CameraMetadata>(characteristics)),
+ mResult(std::make_shared<CameraMetadata>(result)), mThumbnailWidth(0),
+ mThumbnailHeight(0) {}
NativeContext::~NativeContext() {}
@@ -137,6 +145,14 @@
return &mWriter;
}
+std::shared_ptr<const CameraMetadata> NativeContext::getCharacteristics() const {
+ return mCharacteristics;
+}
+
+std::shared_ptr<const CameraMetadata> NativeContext::getResult() const {
+ return mResult;
+}
+
uint32_t NativeContext::getThumbnailWidth() {
return mThumbnailWidth;
}
@@ -626,25 +642,92 @@
// End of DirectStripSource
// ----------------------------------------------------------------------------
-static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, jint width, jint height) {
- bool hasThumbnail = writer->hasIfd(TIFF_IFD_SUB1);
+/**
+ * Given a buffer crop rectangle relative to the pixel array size, and the active array crop
+ * rectangle for the camera characteristics, set the default crop rectangle in the TiffWriter
+ * relative to the buffer crop rectangle origin.
+ */
+static status_t calculateAndSetCrop(JNIEnv* env, const CameraMetadata& characteristics,
+ uint32_t bufXMin, uint32_t bufYMin, uint32_t bufWidth, uint32_t bufHeight,
+ TiffWriter* writer) {
+ camera_metadata_ro_entry entry =
+ characteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+ uint32_t xmin = static_cast<uint32_t>(entry.data.i32[0]);
+ uint32_t ymin = static_cast<uint32_t>(entry.data.i32[1]);
+ uint32_t width = static_cast<uint32_t>(entry.data.i32[2]);
+ uint32_t height = static_cast<uint32_t>(entry.data.i32[3]);
+
+ uint32_t aLeft = xmin;
+ uint32_t aTop = ymin;
+ uint32_t aRight = xmin + width;
+ uint32_t aBottom = ymin + height;
+
+ const uint32_t margin = 8; // Default margin recommended by Adobe for interpolation.
+
+ uint32_t bLeft = bufXMin + margin;
+ uint32_t bTop = bufYMin + margin;
+ uint32_t bRight = bufXMin + bufWidth - margin;
+ uint32_t bBottom = bufYMin + bufHeight - margin;
+
+ uint32_t defaultCropOrigin[] = {std::max(aLeft, bLeft), std::max(aTop, bTop)};
+ uint32_t defaultCropSize[] = {std::min(aRight, bRight) - defaultCropOrigin[0],
+ std::min(aBottom, bBottom) - defaultCropOrigin[1]};
+
+ BAIL_IF_INVALID_R(writer->addEntry(TAG_DEFAULTCROPORIGIN, 2, defaultCropOrigin,
+ TIFF_IFD_0), env, TAG_DEFAULTCROPORIGIN, writer);
+ BAIL_IF_INVALID_R(writer->addEntry(TAG_DEFAULTCROPSIZE, 2, defaultCropSize,
+ TIFF_IFD_0), env, TAG_DEFAULTCROPSIZE, writer);
+
+ return OK;
+}
+
+static bool validateDngHeader(JNIEnv* env, TiffWriter* writer,
+ const CameraMetadata& characteristics, jint width, jint height) {
// TODO: handle lens shading map, etc. conversions for other raw buffer sizes.
- uint32_t metadataWidth = *(writer->getEntry(TAG_IMAGEWIDTH, (hasThumbnail) ? TIFF_IFD_SUB1 :
- TIFF_IFD_0)->getData<uint32_t>());
- uint32_t metadataHeight = *(writer->getEntry(TAG_IMAGELENGTH, (hasThumbnail) ? TIFF_IFD_SUB1 :
- TIFF_IFD_0)->getData<uint32_t>());
-
- if (width < 0 || metadataWidth != static_cast<uint32_t>(width)) {
+ if (width <= 0) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \
- "Metadata width %d doesn't match image width %d", metadataWidth, width);
+ "Image width %d is invalid", width);
return false;
}
- if (height < 0 || metadataHeight != static_cast<uint32_t>(height)) {
+ if (height <= 0) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \
- "Metadata height %d doesn't match image height %d",
- metadataHeight, height);
+ "Image height %d is invalid", height);
+ return false;
+ }
+
+ camera_metadata_ro_entry preCorrectionEntry =
+ characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+ camera_metadata_ro_entry pixelArrayEntry =
+ characteristics.find(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE);
+
+ int pWidth = static_cast<int>(pixelArrayEntry.data.i32[0]);
+ int pHeight = static_cast<int>(pixelArrayEntry.data.i32[1]);
+ int cWidth = static_cast<int>(preCorrectionEntry.data.i32[2]);
+ int cHeight = static_cast<int>(preCorrectionEntry.data.i32[3]);
+
+ bool matchesPixelArray = (pWidth == width && pHeight == height);
+ bool matchesPreCorrectionArray = (cWidth == width && cHeight == height);
+
+ if (matchesPixelArray) {
+ if (calculateAndSetCrop(env, characteristics, 0, 0, static_cast<uint32_t>(pWidth),
+ static_cast<uint32_t>(pHeight), writer) != OK) {
+ return false;
+ }
+ } else if (matchesPreCorrectionArray) {
+ if (calculateAndSetCrop(env, characteristics,
+ static_cast<uint32_t>(preCorrectionEntry.data.i32[0]),
+ static_cast<uint32_t>(preCorrectionEntry.data.i32[1]),
+ static_cast<uint32_t>(preCorrectionEntry.data.i32[2]),
+ static_cast<uint32_t>(preCorrectionEntry.data.i32[3]), writer) != OK) {
+ return false;
+ }
+ } else {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \
+ "Image dimensions (w=%d,h=%d) are invalid, must match either the pixel "
+ "array size (w=%d, h=%d) or the pre-correction array size (w=%d, h=%d)",
+ width, height, pWidth, pHeight, cWidth, cHeight);
return false;
}
@@ -854,7 +937,7 @@
return;
}
- sp<NativeContext> nativeContext = new NativeContext();
+ sp<NativeContext> nativeContext = new NativeContext(characteristics, results);
TiffWriter* writer = nativeContext->getWriter();
writer->addIfd(TIFF_IFD_0);
@@ -906,7 +989,7 @@
{
// Set dimensions
camera_metadata_entry entry =
- characteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+ characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
BAIL_IF_EMPTY(entry, env, TAG_IMAGEWIDTH, writer);
uint32_t width = static_cast<uint32_t>(entry.data.i32[2]);
uint32_t height = static_cast<uint32_t>(entry.data.i32[3]);
@@ -1356,16 +1439,16 @@
}
{
- // Setup default crop + crop origin tags
- uint32_t margin = 8; // Default margin recommended by Adobe for interpolation.
- uint32_t dimensionLimit = 128; // Smallest image dimension crop margin from.
- if (imageWidth >= dimensionLimit && imageHeight >= dimensionLimit) {
- uint32_t defaultCropOrigin[] = {margin, margin};
- uint32_t defaultCropSize[] = {imageWidth - 2 * margin, imageHeight - 2 * margin};
- BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPORIGIN, 2, defaultCropOrigin,
- TIFF_IFD_0), env, TAG_DEFAULTCROPORIGIN, writer);
- BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPSIZE, 2, defaultCropSize,
- TIFF_IFD_0), env, TAG_DEFAULTCROPSIZE, writer);
+ // Set dimensions
+ camera_metadata_entry entry =
+ characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+ BAIL_IF_EMPTY(entry, env, TAG_DEFAULTCROPSIZE, writer);
+ uint32_t xmin = static_cast<uint32_t>(entry.data.i32[0]);
+ uint32_t ymin = static_cast<uint32_t>(entry.data.i32[1]);
+ uint32_t width = static_cast<uint32_t>(entry.data.i32[2]);
+ uint32_t height = static_cast<uint32_t>(entry.data.i32[3]);
+ if (calculateAndSetCrop(env, characteristics, xmin, ymin, width, height, writer) != OK) {
+ return;
}
}
@@ -1874,7 +1957,7 @@
}
// Validate DNG header
- if (!validateDngHeader(env, writer, width, height)) {
+ if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) {
return;
}
@@ -1978,7 +2061,7 @@
}
// Validate DNG header
- if (!validateDngHeader(env, writer, width, height)) {
+ if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) {
return;
}
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 5bef653..63915ed 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -436,6 +436,23 @@
return fmt;
}
+static jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) {
+ ALOGV("nativeDetectSurfaceDataspace");
+ sp<ANativeWindow> anw;
+ if ((anw = getNativeWindow(env, surface)) == NULL) {
+ ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ int32_t fmt = 0;
+ status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt);
+ if(err != NO_ERROR) {
+ ALOGE("%s: Error while querying surface dataspace %s (%d).", __FUNCTION__, strerror(-err),
+ err);
+ return err;
+ }
+ return fmt;
+}
+
static jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz,
jobject surface, jintArray dimens) {
ALOGV("nativeGetSurfaceDimens");
@@ -717,6 +734,9 @@
{ "nativeDetectSurfaceType",
"(Landroid/view/Surface;)I",
(void *)LegacyCameraDevice_nativeDetectSurfaceType },
+ { "nativeDetectSurfaceDataspace",
+ "(Landroid/view/Surface;)I",
+ (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace },
{ "nativeDetectSurfaceDimens",
"(Landroid/view/Surface;[I)I",
(void *)LegacyCameraDevice_nativeDetectSurfaceDimens },
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 91a3c7e..0e2ec6b 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -77,7 +77,7 @@
jobject receiverWeak, const sp<MessageQueue>& messageQueue) :
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mMessageQueue(messageQueue), mWaitingForVsync(false) {
- ALOGV("receiver %p ~ Initializing input event receiver.", this);
+ ALOGV("receiver %p ~ Initializing display event receiver.", this);
}
NativeDisplayEventReceiver::~NativeDisplayEventReceiver() {
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index eb28c4d..98c17c0 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -462,6 +462,12 @@
return event->getActionButton();
}
+static void android_view_MotionEvent_nativeSetActionButton(JNIEnv* env, jclass clazz,
+ jlong nativePtr, jint button) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->setActionButton(button);
+}
+
static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
jlong nativePtr) {
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
@@ -779,6 +785,9 @@
{ "nativeGetActionButton",
"(J)I",
(void*)android_view_MotionEvent_nativeGetActionButton},
+ { "nativeSetActionButton",
+ "(JI)V",
+ (void*)android_view_MotionEvent_nativeSetActionButton},
{ "nativeIsTouchEvent",
"(J)Z",
(void*)android_view_MotionEvent_nativeIsTouchEvent },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5b40d30..9637cf5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -349,20 +349,6 @@
android:description="@string/permdesc_writeContacts"
android:protectionLevel="dangerous" />
- <!-- @deprecated No longer enforced. This was last enforced in API version 22. -->
- <permission android:name="android.permission.READ_PROFILE"
- android:permissionGroup="android.permission-group.CONTACTS"
- android:label="@string/permlab_readProfile"
- android:description="@string/permdesc_readProfile"
- android:protectionLevel="dangerous" />
-
- <!-- @deprecated No longer enforced. This was last enforced in API version 22. -->
- <permission android:name="android.permission.WRITE_PROFILE"
- android:permissionGroup="android.permission-group.CONTACTS"
- android:label="@string/permlab_writeProfile"
- android:description="@string/permdesc_writeProfile"
- android:protectionLevel="dangerous" />
-
<!-- ====================================================================== -->
<!-- Permissions for accessing user's calendar -->
<!-- ====================================================================== -->
@@ -511,42 +497,6 @@
android:description="@string/permdesc_sdcardWrite"
android:protectionLevel="dangerous" />
- <!-- =============================================================== -->
- <!-- Permissions for accessing social info -->
- <!-- =============================================================== -->
- <eat-comment />
-
- <!-- Used for permissions that provide access to the user's social connections,
- such as contacts, call logs, social stream, etc. This includes
- both reading and writing of this data (which should generally be
- expressed as two distinct permissions). -->
-
- <permission-group android:name="android.permission-group.SOCIAL_INFO"
- android:label="@string/permgrouplab_socialInfo"
- android:icon="@drawable/perm_group_social_info"
- android:description="@string/permgroupdesc_socialInfo"
- android:permissionGroupFlags="personalInfo"
- android:priority="1200" />
-
- <!-- Allows an application to read from the user's social stream.
- @deprecated This functionality will be unsupported in the future; cursors returned
- will be empty. Please do not use. -->
- <permission android:name="android.permission.READ_SOCIAL_STREAM"
- android:permissionGroup="android.permission-group.SOCIAL_INFO"
- android:protectionLevel="dangerous"
- android:label="@string/permlab_readSocialStream"
- android:description="@string/permdesc_readSocialStream" />
-
- <!-- Allows an application to write (but not read) the user's
- social stream data.
- @deprecated This functionality will be unsupported in the future; cursors returned
- will be empty. Please do not use. -->
- <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
- android:permissionGroup="android.permission-group.SOCIAL_INFO"
- android:protectionLevel="dangerous"
- android:label="@string/permlab_writeSocialStream"
- android:description="@string/permdesc_writeSocialStream" />
-
<!-- ====================================================================== -->
<!-- Permissions for accessing the device location -->
<!-- ====================================================================== -->
@@ -741,7 +691,41 @@
android:protectionLevel="normal" />
<!-- ====================================================================== -->
- <!-- INSTALLTIME PERMISSIONS -->
+ <!-- REMOVED PERMISSIONS -->
+ <!-- ====================================================================== -->
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.READ_PROFILE"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.WRITE_PROFILE"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.READ_SOCIAL_STREAM"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.READ_USER_DICTIONARY"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- @hide We need to keep this around for backwards compatibility -->
+ <permission android:name="android.permission.WRITE_USER_DICTIONARY"
+ android:protectionLevel="normal"
+ android:permissionFlags="hide"/>
+
+ <!-- ====================================================================== -->
+ <!-- INSTALL PERMISSIONS -->
<!-- ====================================================================== -->
<!-- ================================== -->
@@ -780,36 +764,6 @@
android:protectionLevel="signature|system" />
<!-- =============================================================== -->
- <!-- Permissions for accessing the user dictionary-->
- <!-- =============================================================== -->
- <eat-comment />
-
- <!-- Used for permissions that provide access to the user
- calendar to create / view events.-->
- <permission-group android:name="android.permission-group.USER_DICTIONARY"
- android:label="@string/permgrouplab_dictionary"
- android:icon="@drawable/perm_group_user_dictionary"
- android:description="@string/permgroupdesc_dictionary"
- android:permissionGroupFlags="personalInfo"
- android:priority="1100" />
-
- <!-- Allows an application to read the user dictionary. This should
- really only be required by an IME, or a dictionary editor like
- the Settings app. -->
- <permission android:name="android.permission.READ_USER_DICTIONARY"
- android:permissionGroup="android.permission-group.USER_DICTIONARY"
- android:label="@string/permlab_readDictionary"
- android:description="@string/permdesc_readDictionary"
- android:protectionLevel="dangerous"/>
-
- <!-- Allows an application to write to the user dictionary. -->
- <permission android:name="android.permission.WRITE_USER_DICTIONARY"
- android:permissionGroup="android.permission-group.USER_DICTIONARY"
- android:label="@string/permlab_writeDictionary"
- android:description="@string/permdesc_writeDictionary"
- android:protectionLevel="normal"/>
-
- <!-- =============================================================== -->
<!-- Permissions for setting the device alarm -->
<!-- =============================================================== -->
<eat-comment />
@@ -2090,7 +2044,7 @@
<p>Declaring the permission implies intention to use the API and the user of the
device can grant permission through the Settings application. -->
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
- android:protectionLevel="signature|development|appop" />
+ android:protectionLevel="signature|system|development|appop" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!-- @hide Allows an application to change the app idle state of an app.
@@ -2427,6 +2381,13 @@
<permission android:name="android.permission.LOCAL_MAC_ADDRESS"
android:protectionLevel="signatureOrSystem" />
+ <!-- Allows the Nfc stack to dispatch Nfc messages to applications. Applications
+ can use this permission to ensure incoming Nfc messages are from the Nfc stack
+ and not simulated by another application.
+ @hide -->
+ <permission android:name="android.permission.DISPATCH_NFC_MESSAGE"
+ android:protectionLevel="signatureOrSystem" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
@@ -2450,6 +2411,7 @@
<intent-filter>
<action android:name="android.intent.action.CHOOSER" />
<category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.VOICE" />
</intent-filter>
</activity>
<activity android:name="com.android.internal.app.IntentForwarderActivity"
diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary.png
deleted file mode 100644
index 62fbcdc..0000000
--- a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png
deleted file mode 100644
index c62dd4c..0000000
--- a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary.png
deleted file mode 100644
index a303dc1..0000000
--- a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png
deleted file mode 100644
index 2fc4056..0000000
--- a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png
deleted file mode 100644
index 35d7d5f..0000000
--- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png
deleted file mode 100644
index 74e25ac..0000000
--- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png
deleted file mode 100644
index 8c2cd17..0000000
--- a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png
deleted file mode 100644
index 121d6cf..0000000
--- a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png
deleted file mode 100644
index 5b6ea3b..0000000
--- a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png
deleted file mode 100644
index d92e719..0000000
--- a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png
deleted file mode 100644
index 32942ca..0000000
--- a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png
deleted file mode 100644
index 343551f..0000000
--- a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 4b544d2..2fa2054 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -17,21 +17,24 @@
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layoutDirection="ltr">
+ <!-- Provides a background for the time layout that extends into the button bar area. -->
<View
android:id="@+id/time_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_column="0"
+ android:layout_column="@dimen/time_picker_column_start_material"
android:layout_row="0"
android:layout_rowSpan="3"
- android:layout_gravity="center|fill" />
+ android:layout_gravity="center|fill"
+ android:layoutDirection="locale" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_column="0"
+ android:layout_column="@dimen/time_picker_column_start_material"
android:layout_row="1"
android:layout_gravity="center|fill"
android:paddingStart="?attr/dialogPreferredPadding"
@@ -83,7 +86,8 @@
android:layout_height="wrap_content"
android:layout_below="@+id/time_layout"
android:layout_centerHorizontal="true"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:layoutDirection="locale">
<CheckedTextView
android:id="@+id/am_label"
@@ -116,28 +120,31 @@
android:layout="@layout/alert_dialog_title_material"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_column="1"
+ android:layout_column="@dimen/time_picker_column_end_material"
android:layout_row="0"
- android:layout_gravity="top|fill_horizontal" />
+ android:layout_gravity="top|fill_horizontal"
+ android:layoutDirection="locale" />
<android.widget.RadialTimePickerView
android:id="@+id/radial_picker"
android:layout_width="@dimen/timepicker_radial_picker_dimen"
android:layout_height="@dimen/timepicker_radial_picker_dimen"
- android:layout_column="1"
+ android:layout_column="@dimen/time_picker_column_end_material"
android:layout_row="1"
android:layout_rowWeight="1"
android:layout_gravity="center|fill"
android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
- android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" />
+ android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin"
+ android:layoutDirection="locale" />
<ViewStub
android:id="@id/buttonPanel"
android:layout="@layout/alert_dialog_button_bar_material"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_column="1"
+ android:layout_column="@dimen/time_picker_column_end_material"
android:layout_row="2"
- android:layout_gravity="bottom|fill_horizontal" />
+ android:layout_gravity="bottom|fill_horizontal"
+ android:layoutDirection="locale" />
</GridLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 03cee7d..aa025b9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dae"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Persoonlike programme"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Persoonlik"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"gaan by jou kontakte in"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a676a3d..887f5bc 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ቀኖች"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ቀን <xliff:g id="HOURS">%2$d</xliff:g> ሰዓ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ቀን <xliff:g id="HOURS">%2$d</xliff:g> ሰዓ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android ስርዓት"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"የግል መተግበሪያዎች"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"የግል"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ስራ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ዕውቂያዎች"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"የእርስዎ እውቂያዎች ላይ ይድረሱባቸው"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4d5e798..19bc8f6 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"غيغابايت"</string>
<string name="terabyteShort" msgid="231613018159186962">"تيرابايت"</string>
<string name="petabyteShort" msgid="5637816680144990219">"بيتابايت"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> يوم"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> يوم <xliff:g id="HOURS">%2$d</xliff:g> ساعة"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> يوم <xliff:g id="HOURS">%2$d</xliff:g> ساعة"</string>
@@ -229,7 +228,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"نظام Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"التطبيقات الشخصية"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"شخصي"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"عمل"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"جهات الاتصال"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"الوصول إلى جهات اتصالك"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 3f2e6af..de6dce4 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> gün"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> gan <xliff:g id="HOURS">%2$d</xliff:g> saat"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> saat"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistemi"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Şəxsi tətbiqlər"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Şəxsi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"İş"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarınıza daxil olun"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 21969d0..c722256 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
<string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дни"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Системно от Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Лични приложения"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Личен"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Служебен"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"достъп до контактите ви"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 3d4d800..b8a204b 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> দিন"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
<string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android সিস্টেম"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ব্যক্তিগত অ্যাপ্লিকেশানগুলি"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ব্যক্তিগত"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"কর্মক্ষেত্র"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"পরিচিতি"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"আপনার পরিচিতিগুলিতে অ্যাক্সেস করুন"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 81ced84..abe460e 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dies"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicacions personals"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Feina"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactes"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedir als contactes"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8b92c84..1a80267 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Osobní aplikace"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Osobní"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Práce"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"přístup ke kontaktům"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index af6aa5a..f91a069a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"Tb"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Pb"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dage"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Personlige apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personlig"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Arbejde"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersoner"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8e9a6ac..978a2b7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> Tage"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> Tag <xliff:g id="HOURS">%2$d</xliff:g> Std."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> Tag <xliff:g id="HOURS">%2$d</xliff:g> Std."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Private Apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Privat"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Geschäftlich"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"Auf Kontakte zuzugreifen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8d1779c..a5e8ddd 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ημέρες"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ημ. <xliff:g id="HOURS">%2$d</xliff:g> ώρες"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ημ. <xliff:g id="HOURS">%2$d</xliff:g> ώρα"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
<string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Προσωπικές εφαρμογές"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Προσωπικό"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Εργασία"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Επαφές"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"πρόσβαση στις επαφές σας"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 7e89393..ef20cec 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</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="6465364741001216388">"Personal apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 7e89393..ef20cec 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</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="6465364741001216388">"Personal apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7e89393..ef20cec 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> days"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</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="6465364741001216388">"Personal apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d3a4d61..d0a0c70 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a los contactos"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index baf4601..3839d86 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"> 999"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a tus contactos"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 0eb270c..3c8a0ca 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> päeva"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> päev <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> päev <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Isiklikud rakendused"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Isiklik"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Töö"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktid"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"juurdepääs kontaktidele"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 0a2e8b3..27275bc 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> egun"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> egun <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> egun <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistema"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplikazio pertsonalak"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Pertsonalak"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Lana"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"Atzitu kontaktuak"</string>
@@ -729,7 +728,7 @@
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Eredua marrazten hasi zara"</string>
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Eredua garbitu da"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Gelaxka gehitu da"</string>
- <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Gehitu da <xliff:g id="CELL_INDEX">%1$s</xliff:g> konexio zelularra"</string>
+ <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Gehitu da <xliff:g id="CELL_INDEX">%1$s</xliff:g> puntua"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Eredua osatu da"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d/%3$d widgeta."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Gehitu widgeta."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 4a6e425..5efbd5ce 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"گیگابایت"</string>
<string name="terabyteShort" msgid="231613018159186962">"ترابایت"</string>
<string name="petabyteShort" msgid="5637816680144990219">"پتابایت"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> روز"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> روز و <xliff:g id="HOURS">%2$d</xliff:g> ساعت"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> روز و <xliff:g id="HOURS">%2$d</xliff:g> ساعت"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
<string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"برنامههای شخصی"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"شخصی"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"محل کار"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"مخاطبین"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"دسترسی به مخاطبین شما"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 295028e..981f117 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"Gt"</string>
<string name="terabyteShort" msgid="231613018159186962">"Tt"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Pt"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> päivää"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> päivä <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> päivä <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Omat sovellukset"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Henkilökoht."</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Työ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktit"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"käyttää yhteystietoja"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3f4f64e..bfa55b9 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
<string name="terabyteShort" msgid="231613018159186962">"To"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> jours"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Travail"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index bac4417..5a9b8ca 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
<string name="terabyteShort" msgid="231613018159186962">"To"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> jours"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> j et <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Professionnel"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index c2dcd0c..6a79b89 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicacións persoais"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Persoal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Traballo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder aos teus contactos"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 8a75dbe..51f9855 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ <xliff:g id="HOURS">%2$d</xliff:g> કલાક"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> દિવસ <xliff:g id="HOURS">%2$d</xliff:g> કલાક"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android સિસ્ટમ"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"વ્યક્તિગત એપ્લિકેશન્સ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"વ્યક્તિગત"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"કાર્યાલય"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"સંપર્કો"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"તમારા સંપર્કોને ઍક્સેસ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 90ac653..fff0377 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिन"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिन <xliff:g id="HOURS">%2$d</xliff:g> घंटे"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिन <xliff:g id="HOURS">%2$d</xliff:g> घंटा"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"व्यक्तिगत ऐप्स"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"व्यक्तिगत"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"कार्यालय"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"अपने संपर्कों को ऐक्सेस करें"</string>
@@ -1272,7 +1271,7 @@
<string name="validity_period" msgid="8818886137545983110">"मान्यता:"</string>
<string name="issued_on" msgid="5895017404361397232">"जारी करने का दिनांक:"</string>
<string name="expires_on" msgid="3676242949915959821">"समय समाप्ति दिनांक:"</string>
- <string name="serial_number" msgid="758814067660862493">"क्रमांक:"</string>
+ <string name="serial_number" msgid="758814067660862493">"सीरियल नंबर:"</string>
<string name="fingerprints" msgid="4516019619850763049">"फ़िंगरप्रिंट:"</string>
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 फ़िंगरप्रिंट:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 फ़िंगरप्रिंट:"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 7ada3f0..a18bc4b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -226,7 +225,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Osobne aplikacije"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Osobno"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Posao"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupati vašim kontaktima"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 70f006e..bd48e8c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> nap"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> nap <xliff:g id="HOURS">%2$d</xliff:g> óra"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> nap <xliff:g id="HOURS">%2$d</xliff:g> óra"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Személyes alkalmazások"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Személyes"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Munkahelyi"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Névjegyek"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"hozzáférés a névjegyekhez"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 806d70a..535f7a6 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string>
<string name="terabyteShort" msgid="231613018159186962">"Տբ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> օր"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> օր <xliff:g id="HOURS">%2$d</xliff:g> ժ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> օր <xliff:g id="HOURS">%2$d</xliff:g> ժ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Անձնական ծրագրեր"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Անձնական"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Աշխատանքային"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Կոնտակտներ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"կոնտակտների հասանելիություն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ffbf564..fe61d55 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> hari"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplikasi pribadi"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Pribadi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Kantor"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontak"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"mengakses kontak"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index cfc3ea4..3b52f61 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagar"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> klst."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> klst."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android kerfið"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Persónuleg forrit"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Persónulegt"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Vinna"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Tengiliðir"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"fá aðgang að tengiliðunum þínum"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3e18bcd..4f074bc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> giorni"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> giorno <xliff:g id="HOURS">%2$d</xliff:g> ore"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> giorno <xliff:g id="HOURS">%2$d</xliff:g> ora"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"App personali"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personale"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Lavoro"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatti"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"accesso ai contatti"</string>
@@ -1547,7 +1546,7 @@
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Altre opzioni"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Chiudi overflow"</string>
<plurals name="selected_count" formatted="false" msgid="7187339492915744615">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elemento selezionato</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elementi selezionati</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi selezionati</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento selezionato</item>
</plurals>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1e3f8cd..0103049 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ימים"</string>
<string name="durationDayHours" msgid="2713107458736744435">"יום <xliff:g id="DAYS">%1$d</xliff:g> <xliff:g id="HOURS">%2$d</xliff:g> שע\'"</string>
<string name="durationDayHour" msgid="7293789639090958917">"יום <xliff:g id="DAYS">%1$d</xliff:g> שעה <xliff:g id="HOURS">%2$d</xliff:g>"</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
<string name="android_system_label" msgid="6577375335728551336">"מערכת Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"אפליקציות אישיות"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"אישי"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"עבודה"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"אנשי קשר"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"גישה אל אנשי הקשר"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 009f4f0..d3e1e7f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>日"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>日<xliff:g id="HOURS">%2$d</xliff:g>時間"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>日<xliff:g id="HOURS">%2$d</xliff:g>時間"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
<string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"プライベートアプリ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"プライベート"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"職場"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"連絡先"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"連絡先へのアクセス"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 0224308..bfeac1d 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"გბაიტი"</string>
<string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> დღე"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> დღე <xliff:g id="HOURS">%2$d</xliff:g> სთ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> დღე <xliff:g id="HOURS">%2$d</xliff:g> სთ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"პერსონალური აპები"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"პირადი"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"სამსახური"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"კონტაქტები"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"თქვენს კონტაქტებზე წვდომა"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index f2d15fe..e9b3709 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
<string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> күн"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> сағ."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> сағ."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android жүйесі"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Жеке қолданбалар"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Жеке"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Жұмыс"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактілер"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"контактілерге кіру"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index e9c2a05..d437294 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ជីកាបៃ"</string>
<string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ <xliff:g id="HOURS">%2$d</xliff:g> ម៉ោង"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ថ្ងៃ <xliff:g id="HOURS">%2$d</xliff:g> ម៉ោង"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string>
<string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"កម្មវិធីផ្ទាល់ខ្លួន"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ផ្ទាល់ខ្លួន"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"កន្លែងធ្វើការ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ទំនាក់ទំនង"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ចូលប្រើទំនាក់ទំនងរបស់អ្នក"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 9b7e4a9..325f377 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನಗಳು"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನ <xliff:g id="HOURS">%2$d</xliff:g> ಗಂಟೆಗಳು"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ದಿನ <xliff:g id="HOURS">%2$d</xliff:g> ಗಂ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android ಸಿಸ್ಟಂ"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ವೈಯಕ್ತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ವೈಯಕ್ತಿಕ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ಕಚೇರಿ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ಸಂಪರ್ಕಗಳು"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
@@ -902,7 +901,7 @@
<string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ಜೊತೆಗೆ ತೆರೆಯಿರಿ"</string>
<string name="whichEditApplication" msgid="144727838241402655">"ಇವರ ಜೊತೆಗೆ ಸಂಪಾದಿಸಿ"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ಜೊತೆಗೆ ಸಂಪಾದಿಸಿ"</string>
- <string name="whichSendApplication" msgid="6902512414057341668">"ಇದರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="whichSendApplication" msgid="6902512414057341668">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="whichHomeApplication" msgid="4307587691506919691">"ಹೋಮ್ ಅಪ್ಲಿಕೇಶನ್ ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"ಹೋಮ್ ಎಂಬಂತೆ %1$s ಅನ್ನು ಬಳಸಿ"</string>
@@ -1066,8 +1065,8 @@
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ನಿಮ್ಮ USB ಸಂಗ್ರಹಣೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಎಲ್ಲಾ ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಿಹಾಕಲಾಗುವುದು. ಈ ಕ್ರಿಯೆಯನ್ನು ಹಿಂತಿರುಗಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ!"</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"ನಿಮ್ಮ ಕಾರ್ಡ್ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದುಹೋಗುತ್ತದೆ."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"ಸ್ವರೂಪಿಸು"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗಿಂಗ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
<string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"ಕೀಬೋರ್ಡ್ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="show_ime" msgid="9157568568695230830">"ಇನ್ಪುಟ್ ವಿಧಾನವನ್ನು ತೋರಿಸು"</string>
@@ -1231,7 +1230,7 @@
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ನಮೂದಿಸು"</string>
<string name="activitychooserview_choose_application" msgid="2125168057199941199">"ಅಪ್ಲಿಕೇಶನ್ವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"ಇದರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"ಸ್ಲೈಡಿಂಗ್ ಹ್ಯಾಂಡಲ್. ಸ್ಪರ್ಶಿಸಿ & ಇರಿಸಿ."</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಸ್ವೈಪ್ ಮಾಡಿ."</string>
@@ -1278,7 +1277,7 @@
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 ಫಿಂಗರ್ಪ್ರಿಂಟ್:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ಎಲ್ಲವನ್ನೂ ನೋಡಿ"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ಚಟುವಟಿಕೆಯನ್ನು ಆರಿಸಿ"</string>
- <string name="share_action_provider_share_with" msgid="5247684435979149216">"ಇದರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="share_action_provider_share_with" msgid="5247684435979149216">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
<string name="sending" msgid="3245653681008218030">"ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ..."</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"ಬ್ರೌಸರ್ ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 471da5f..3766ec0 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>일"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>일 <xliff:g id="HOURS">%2$d</xliff:g>시간"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>일 <xliff:g id="HOURS">%2$d</xliff:g>시간"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"개인 앱"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"개인"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"직장"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"주소록"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"주소록 액세스"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 7076ee0..91eaab6 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -32,8 +32,7 @@
<skip />
<!-- no translation found for petabyteShort (5637816680144990219) -->
<skip />
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> күн"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
@@ -333,7 +332,7 @@
<skip />
<!-- no translation found for android_system_label (6577375335728551336) -->
<skip />
- <string name="user_owner_label" msgid="6465364741001216388">"Жеке колдономолор"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Жеке"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Жумуш"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Байланыштар"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"байланыштарыңызга уруксат"</string>
diff --git a/core/res/res/values-ldrtl/dimens.xml b/core/res/res/values-ldrtl/dimens.xml
new file mode 100644
index 0000000..807c042
--- /dev/null
+++ b/core/res/res/values-ldrtl/dimens.xml
@@ -0,0 +1,20 @@
+<?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>
+ <item type="dimen" format="integer" name="time_picker_column_start_material">1</item>
+ <item type="dimen" format="integer" name="time_picker_column_end_material">0</item>
+</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index a0384c2..767defb 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້ <xliff:g id="HOURS">%2$d</xliff:g> ຊມ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ມື້ <xliff:g id="HOURS">%2$d</xliff:g> ຊມ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ແອັບຯສ່ວນໂຕ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ສ່ວນໂຕ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ບ່ອນເຮັດວຽກ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ລາຍຊື່"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ເຂົ້າຫາລາຍຊື່ຂອງທ່ານ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f5d35d3..bd59ebf 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> val."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> val."</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
<string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Asmeninės programos"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Asmeninė"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Darbo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktai"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"pasiekti kontaktus"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9e4cd5f..fe6d530 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -226,7 +225,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
<string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Personīgās lietotnes"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personisks"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Darba"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersonas"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"piekļūt jūsu kontaktpersonu datiem"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 25d9264..e7f2970 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
<string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дена"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ден <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбеден режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Систем Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Лични апликации"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Лични"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"пристапи до контактите"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 7b73a48..1372ea6 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം <xliff:g id="HOURS">%2$d</xliff:g> മണിക്കൂർ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ദിവസം <xliff:g id="HOURS">%2$d</xliff:g> മണിക്കൂർ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android സിസ്റ്റം"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"വ്യക്തിഗത അപ്ലിക്കേഷനുകൾ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"വ്യക്തിഗതം"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"കോൺടാക്റ്റുകൾ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ്സ് ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 42b8902..a287a46 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
<string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр <xliff:g id="HOURS">%2$d</xliff:g> цаг"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> өдөр <xliff:g id="HOURS">%2$d</xliff:g> цаг"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Хувийн апп-ууд"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Хувийн"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Ажил"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Харилцагчдын хаяг"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"харилцагч руугаа хандах"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 80a1d61..64db2be 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस <xliff:g id="HOURS">%2$d</xliff:g> तास"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिवस <xliff:g id="HOURS">%2$d</xliff:g> तास"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"वैयक्तिक अॅप्स"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"वैयक्तिक"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"कार्य"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"आपल्या संपर्कांवर प्रवेश करा"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 60685c4..9a576e1 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> hari"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> hari <xliff:g id="HOURS">%2$d</xliff:g> jam"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Apl peribadi"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Peribadi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Tempat Kerja"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kenalan"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"akses kenalan anda"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 3885d976..8c5bf14 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ရက်"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ရက် <xliff:g id="HOURS">%2$d</xliff:g> နာရီ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ရက်<xliff:g id="HOURS">%2$d</xliff:g> နာရီ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
<string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android စနစ်"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ကိုယ်ပိုင် appများ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ကိုယ်ရေး"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"အလုပ်"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"အဆက်အသွယ်များ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"သင့် အဆက်အသွယ်များအား ဝင်ရောက်သုံးရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 77880d8..6a2fb12 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dager"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> t"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Personlige apper"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personlig"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Jobb"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"få tilgang til kontaktene dine"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 04dc806..0812866 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> दिन"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> दिन<xliff:g id="HOURS">%2$d</xliff:g> घन्टा"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> दिन<xliff:g id="HOURS">%2$d</xliff:g> घन्टा"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"व्यक्तिगत अनुप्रयोगहरू"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"व्यक्तिगत"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"काम"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"सम्पर्कहरू"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"तपाईँको सम्पर्कमा पहुँच गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 28d86c8..23a4ca2 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagen"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> uur"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Persoonlijke apps"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Persoonlijk"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacten"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot uw contacten"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 8ce1a9b..fba7a81 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ <xliff:g id="HOURS">%2$d</xliff:g> ਘੰਟੇ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ਦਿਨ <xliff:g id="HOURS">%2$d</xliff:g> ਘੰਟਾ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ਨਿੱਜੀ ਐਪਸ"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ਨਿੱਜੀ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ਕੰਮ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਨੂੰ ਐਕਸੈਸ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 1737626..3c895cc 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dni"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dzień <xliff:g id="HOURS">%2$d</xliff:g> godz."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dzień <xliff:g id="HOURS">%2$d</xliff:g> godz."</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
<string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplikacje osobiste"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Osobiste"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Praca"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostęp do kontaktów"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7ec15e3..a9968cc 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dias"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicações pessoais"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"aceder aos contactos"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a4e93ad..1112bdb 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dias"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dia <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Apps pessoais"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"acessar seus contatos"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b2031c6..347439c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TO"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PO"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> (de) zile"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> zile <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> zi <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -226,7 +225,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplicații personale"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Serviciu"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Persoane de contact"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"accesează persoanele de contact"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 58ffa3b..2532852 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
<string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дн."</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> ч."</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Персональные приложения"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Личные данные"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакты"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"доступ к контактам"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 58cb2ea..b866db2 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"දින <xliff:g id="DAYS">%1$d</xliff:g>"</string>
<string name="durationDayHours" msgid="2713107458736744435">"දින <xliff:g id="DAYS">%1$d</xliff:g> පැය <xliff:g id="HOURS">%2$d</xliff:g>"</string>
<string name="durationDayHour" msgid="7293789639090958917">"දින <xliff:g id="DAYS">%1$d</xliff:g> පැය <xliff:g id="HOURS">%2$d</xliff:g>"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"ආරක්ෂිත ආකාරය"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"පුද්ගලික යෙදුම්"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"පෞද්ගලික"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"කාර්යාලය"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"සම්බන්ධතා"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ඔබේ සම්බන්ධතාවලට පිවිසෙන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 124bef9..73b9be7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> d."</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> hod."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d. <xliff:g id="HOURS">%2$d</xliff:g> hod."</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Osobné aplikácie"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Osobné"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Práca"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"prístup k vašim kontaktom"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index efcdee9..2296350 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"Št. dni: <xliff:g id="DAYS">%1$d</xliff:g>"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Osebne aplikacije"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Osebno"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Služba"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Stiki"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostop do stikov"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 26dee97..d5ec38c 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"terabajt"</string>
<string name="petabyteShort" msgid="5637816680144990219">"petabajt"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ditë"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ditë e <xliff:g id="HOURS">%2$d</xliff:g> orë"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ditë e <xliff:g id="HOURS">%2$d</xliff:g> orë"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemi \"android\""</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Aplikacione personale"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Puna"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktet"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"qasu te kontaktet e tua"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e2209e6..3a158ae 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дана"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> дан <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> дан <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
@@ -226,7 +225,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Личне апликације"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Лично"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Посао"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"приступ контактима"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3f7de17..7f22323 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dagar"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> tim"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dag <xliff:g id="HOURS">%2$d</xliff:g> tim"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Personliga appar"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personligt"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Arbetet"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"få tillgång till dina kontakter"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1dd01bc..20a750e 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"Siku <xliff:g id="DAYS">%1$d</xliff:g>"</string>
<string name="durationDayHours" msgid="2713107458736744435">"Siku <xliff:g id="DAYS">%1$d</xliff:g> saa <xliff:g id="HOURS">%2$d</xliff:g>"</string>
<string name="durationDayHour" msgid="7293789639090958917">"Siku <xliff:g id="DAYS">%1$d</xliff:g> saa <xliff:g id="HOURS">%2$d</xliff:g>"</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
<string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Programu binafsi"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Binafsi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Kazini"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Anwani"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"fikia anwani zako"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 1140cc1..1acab80 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"ஜி.பை."</string>
<string name="terabyteShort" msgid="231613018159186962">"டெ.பை."</string>
<string name="petabyteShort" msgid="5637816680144990219">"பெ.பை."</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> நாட்கள்"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> நாள் <xliff:g id="HOURS">%2$d</xliff:g> ம.நே."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> நாள் <xliff:g id="HOURS">%2$d</xliff:g> ம.நே."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android அமைப்பு"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"தனிப்பட்ட பயன்பாடுகள்"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"தனிப்பட்ட"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"பணியிடம்"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"தொடர்புகள்"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"தொடர்புகளை அணுகும்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 115c1cc..69b2465 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> రోజులు"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> రో <xliff:g id="HOURS">%2$d</xliff:g> గం"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> రో <xliff:g id="HOURS">%2$d</xliff:g> గం"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android సిస్టమ్"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"వ్యక్తిగత అనువర్తనాలు"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"వ్యక్తిగతం"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"కార్యాలయం"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"పరిచయాలు"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"మీ పరిచయాలను ప్రాప్యత చేస్తుంది"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0b37f27..0f17334 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> วัน"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> วัน <xliff:g id="HOURS">%2$d</xliff:g> ชม."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> วัน <xliff:g id="HOURS">%2$d</xliff:g> ชม."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
<string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"แอปส่วนตัว"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ส่วนตัว"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ที่ทำงาน"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"รายชื่อติดต่อ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"เข้าถึงรายชื่อติดต่อ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6dd35d4..7c91b09 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> (na) araw"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> day <xliff:g id="HOURS">%2$d</xliff:g> hr"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</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="6465364741001216388">"Mga personal na app"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabaho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Mga Contact"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ina-access ang iyong mga contact"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7fd1fc2..192adb9 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> gün"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> sa."</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> gün <xliff:g id="HOURS">%2$d</xliff:g> sa."</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Kişisel uygulamalar"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Kişisel"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"İş"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kişiler"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"kişilerinize erişme"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 61e487c..7ad6f1d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string>
<string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дн."</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> день <xliff:g id="HOURS">%2$d</xliff:g> год"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> дн. <xliff:g id="HOURS">%2$d</xliff:g> год"</string>
@@ -227,7 +226,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Особисті додатки"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Особисті дані"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Службовий профіль"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"отримувати доступ до контактів"</string>
@@ -731,7 +730,7 @@
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Малювання ключа розпочалося"</string>
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Ключ очищено"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Телефон додано"</string>
- <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Додано клітинку <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
+ <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Додано крапку <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Малювання ключа закінчено"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Віджет %2$d з %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додати віджет."</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 38bdec8..bee9998 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> دن"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> دن <xliff:g id="HOURS">%2$d</xliff:g> گھنٹے"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> دن <xliff:g id="HOURS">%2$d</xliff:g> گھنٹہ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android سسٹم"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"ذاتی ایپس"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"ذاتی"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"دفتر"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"رابطے"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"اپنے رابطوں تک رسائی حاصل کریں"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index e3eb789..d817e11 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> kun"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> kun <xliff:g id="HOURS">%2$d</xliff:g> soat"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> kun <xliff:g id="HOURS">%2$d</xliff:g> soat"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android tizimi"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Shaxsiy ilovalar"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Shaxsiy"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Ish"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarga kirish"</string>
@@ -729,7 +728,7 @@
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Chizma namunasi ishga tushirildi"</string>
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Chizma namunasi tozalandi"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Katak qo‘shildi"</string>
- <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> qo‘shildi"</string>
+ <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> katak qo‘shildi"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Chizma namunasi tugatildi"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidjet %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidjet qo‘shish."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 1a2c8d3..f00bd88 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> ngày"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> ngày <xliff:g id="HOURS">%2$d</xliff:g> giờ"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> ngày <xliff:g id="HOURS">%2$d</xliff:g> giờ"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
<string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Ứng dụng cá nhân"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Cá nhân"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Cơ quan"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Danh bạ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"truy cập vào danh bạ của bạn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index a7b4344..9e42c8c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g>天"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g>天<xliff:g id="HOURS">%2$d</xliff:g>小时"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g>天<xliff:g id="HOURS">%2$d</xliff:g>小时"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android系统"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"个人应用"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"个人"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"工作"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"通讯录"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"使用您的通讯录"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 097acfa..5d54d76 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> 天"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"個人"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"通訊錄"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取您的通訊錄"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a64ff187..b96f2d0 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> 天"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> 天 <xliff:g id="HOURS">%2$d</xliff:g> 小時"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"個人"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"聯絡人"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取您的聯絡人"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5794daf..92839d1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -26,8 +26,7 @@
<string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
- <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
- <skip />
+ <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> izinsuku"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> usuku <xliff:g id="HOURS">%2$d</xliff:g> amahora"</string>
<string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> usuku <xliff:g id="HOURS">%2$d</xliff:g> ihora"</string>
@@ -225,7 +224,7 @@
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string>
<string name="android_system_label" msgid="6577375335728551336">"Uhlelo lwe-Android"</string>
- <string name="user_owner_label" msgid="6465364741001216388">"Izinhlelo zokusebenza zomuntu siqu"</string>
+ <string name="user_owner_label" msgid="2804351898001038951">"Okomuntu siqu"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Umsebenzi"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Oxhumana nabo"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"finyelela koxhumana nabo"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f31c1d6..3cb4d7c 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -231,6 +231,9 @@
may cost the user money. Such permissions may be highlighted
when shown to the user with this additional information. -->
<flag name="costsMoney" value="0x0001" />
+ <!-- Additional flag from base permission type: this permission is hidden
+ and should not show in the UI. -->
+ <flag name="hide" value="0x2" />
</attr>
<!-- Specified the name of a group that this permission is associated
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 424a0b7..f6cefba 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -157,6 +157,15 @@
ActivityManager based on screen size. -->
<integer name="config_extraFreeKbytesAdjust">0</integer>
+ <!-- Set this to true to enable the platform's auto-power-save modes like doze and
+ app standby. These are not enabled by default because they require a standard
+ cloud-to-device messaging service for apps to interact correctly with the modes
+ (such as to be able to deliver an instant message to the device even when it is
+ dozing). This should be enabled if you have such services and expect apps to
+ correctly use them when installed on your device. Otherwise, keep this disabled
+ so that applications can still use their own mechanisms. -->
+ <bool name="config_enableAutoPowerModes">false</bool>
+
<!-- The duration (in milliseconds) that the radio will scan for a signal
when there's no network connection. If the scan doesn't timeout, use zero -->
<integer name="config_radioScanningTimeout">0</integer>
@@ -359,6 +368,9 @@
<!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
<bool translatable="false" name="config_wifi_dual_band_support">false</bool>
+ <!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled -->
+ <bool translatable="false" name="config_wifi_hotspot2_enabled">true</bool>
+
<!-- Device type information conforming to Annex B format in WiFi Direct specification.
The default represents a dual-mode smartphone -->
<string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string>
@@ -1831,6 +1843,19 @@
<item>com.android.inputmethod.latin</item>
</string-array>
+ <!-- The list of carrier applications which should be disabled until used.
+ This function suppresses update notifications for these pre-installed apps.
+ In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the
+ following conditions are met.
+ 1. Not currently carrier-privileged according to the inserted SIM
+ 2. Pre-installed
+ 3. In the default state (enabled but not explicitly)
+ And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted
+ that marks the app as carrier privileged. It also grants the app default permissions
+ for Phone and Location. As such, apps MUST only ever be added to this list if they
+ obtain user consent to access their location through other means. -->
+ <string-array name="config_disabledUntilUsedPreinstalledCarrierApps" translatable="false" />
+
<!-- The list of classes that should be added to the notification ranking pipline.
See {@link com.android.server.notification.NotificationSignalExtractor} -->
<string-array name="config_notificationSignalExtractors">
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 7e74680..09c1e6f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -385,21 +385,24 @@
<item type="dimen" format="float" name="ambient_shadow_alpha">0.039</item>
<item type="dimen" format="float" name="spot_shadow_alpha">0.19</item>
- <!-- Floating toolbar dimensions -->
- <dimen name="floating_toolbar_height">48dp</dimen>
- <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen>
- <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen>
- <dimen name="floating_toolbar_menu_button_side_padding">16dp</dimen>
- <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen>
- <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen>
- <dimen name="floating_toolbar_text_size">14sp</dimen>
- <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen>
- <dimen name="floating_toolbar_preferred_width">328dp</dimen>
- <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen>
- <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen>
- <dimen name="floating_toolbar_horizontal_margin">16dp</dimen>
- <dimen name="floating_toolbar_vertical_margin">8dp</dimen>
- <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
+ <!-- Floating toolbar dimensions -->
+ <dimen name="floating_toolbar_height">48dp</dimen>
+ <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen>
+ <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen>
+ <dimen name="floating_toolbar_menu_button_side_padding">16dp</dimen>
+ <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen>
+ <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen>
+ <dimen name="floating_toolbar_text_size">14sp</dimen>
+ <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen>
+ <dimen name="floating_toolbar_preferred_width">328dp</dimen>
+ <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen>
+ <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen>
+ <dimen name="floating_toolbar_horizontal_margin">16dp</dimen>
+ <dimen name="floating_toolbar_vertical_margin">8dp</dimen>
+ <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
- <dimen name="chooser_grid_padding">0dp</dimen>
+ <dimen name="chooser_grid_padding">0dp</dimen>
+
+ <item type="dimen" format="integer" name="time_picker_column_start_material">0</item>
+ <item type="dimen" format="integer" name="time_picker_column_end_material">1</item>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ea0d349..246e43a33 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -554,11 +554,6 @@
<string name="permgroupdesc_location">access this device\'s location</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgrouplab_socialInfo">Your social information</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgroupdesc_socialInfo">Direct access to information about your contacts and social connections.</string>
-
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_calendar">Calendar</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_calendar">access your calendar</string>
@@ -573,16 +568,6 @@
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_storage">access photos, media, and files on your device</string>
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgrouplab_dictionary">User Dictionary</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgroupdesc_dictionary">Read or write words in user dictionary.</string>
-
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgrouplab_bookmarks">Bookmarks and History</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permgroupdesc_bookmarks">Direct access to bookmarks and browser history.</string>
-
<!-- Title of a category of application permissioncds, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_microphone">Microphone</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -901,23 +886,6 @@
<string name="permdesc_writeCallLog" product="default">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>
-
- <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] -->
- <string name="permlab_readProfile">read your own contact card</string>
- <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] -->
- <string name="permdesc_readProfile" product="default">Allows the app to read
- personal profile information stored on your device, such as your name and
- contact information. This means the app can identify you and may send your
- profile information to others.</string>
-
- <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] -->
- <string name="permlab_writeProfile">modify your own contact card</string>
- <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] -->
- <string name="permdesc_writeProfile" product="default">Allows the app to
- change or add to personal profile information stored on your device, such
- as your name and contact information. This means the app can identify you
- and may send your profile information to others.</string>
-
<!-- Title of the body sensors permission, listed so the user can decide whether to allow the application to access body sensor data. [CHAR LIMIT=30] -->
<string name="permlab_bodySensors">body sensors (like heart rate monitors)
</string>
@@ -925,23 +893,6 @@
<string name="permdesc_bodySensors" product="default">Allows the app to access data from sensors
that monitor your physical condition, such as your heart rate.</string>
- <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] -->
- <string name="permlab_readSocialStream" product="default">read your social stream</string>
- <string name="permdesc_readSocialStream" product="default">Allows the app
- to access and sync social updates from you and your friends. Be careful
- when sharing information -- this allows the app to read communications
- between you and your friends on social networks, regardless of
- confidentiality. Note: this permission may not be enforced on all social
- networks.</string>
-
- <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] -->
- <string name="permlab_writeSocialStream" product="default">write to your social stream</string>
- <string name="permdesc_writeSocialStream" product="default">Allows the app to
- display social updates from your friends. Be careful when sharing
- information -- this allows the app to produce messages that may appear to
- come from a friend. Note: this permission may not be enforced on all social
- networks.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">read calendar events plus confidential information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1285,18 +1236,6 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readSyncStats">Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced. </string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_readDictionary">read terms you added to the dictionary</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_readDictionary">Allows the app to read all words,
- names and phrases that the user may have stored in the user dictionary.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_writeDictionary">add words to user-defined dictionary</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_writeDictionary">Allows the app to write new words into the
- user dictionary.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
<string name="permlab_sdcardRead" product="nosdcard">read the contents of your USB storage</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 295251c..3a1a156 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -251,6 +251,7 @@
<java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
<java-symbol type="bool" name="config_cellBroadcastAppLinks" />
<java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
+ <java-symbol type="bool" name="config_enableAutoPowerModes" />
<java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
<java-symbol type="bool" name="config_enable_puk_unlock_screen" />
<java-symbol type="bool" name="config_enableBurnInProtection" />
@@ -1127,6 +1128,7 @@
<java-symbol type="array" name="special_locale_names" />
<java-symbol type="array" name="config_cdma_dun_supported_types" />
<java-symbol type="array" name="config_disabledUntilUsedPreinstalledImes" />
+ <java-symbol type="array" name="config_disabledUntilUsedPreinstalledCarrierApps" />
<java-symbol type="array" name="config_operatorConsideredNonRoaming" />
<java-symbol type="array" name="config_sameNamedOperatorConsideredRoaming" />
<java-symbol type="array" name="config_callBarringMMI" />
@@ -1647,6 +1649,7 @@
<java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
<java-symbol type="bool" name="config_wifi_background_scan_support" />
<java-symbol type="bool" name="config_wifi_dual_band_support" />
+ <java-symbol type="bool" name="config_wifi_hotspot2_enabled" />
<java-symbol type="bool" name="config_wimaxEnabled" />
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
@@ -2314,4 +2317,6 @@
<java-symbol type="plurals" name="selected_count" />
<java-symbol type="drawable" name="ic_dialog_alert_material" />
+ <java-symbol type="bool" name="allow_stacked_button_bar" />
+
</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 18c83b4..9548e51 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -93,11 +93,11 @@
<!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements -->
- <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" />
+ <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101" />
<!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf -->
- <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" />
+ <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|887" />
<!-- Georgia: 4 digits, known premium codes listed -->
<shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
@@ -184,6 +184,6 @@
<shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
<!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
- <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="87902" />
+ <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" />
</shortcodes>
diff --git a/docs/html/about/versions/android-4.0.3.jd b/docs/html/about/versions/android-4.0.3.jd
index 5fa8547..4c2ccb9 100644
--- a/docs/html/about/versions/android-4.0.3.jd
+++ b/docs/html/about/versions/android-4.0.3.jd
@@ -78,19 +78,19 @@
stream along with photos for each.</p>
<p>The database table that contains an individual contact’s social stream is
-defined by {@link android.provider.ContactsContract.StreamItems}, the Uri for
+defined by android.provider.ContactsContract.StreamItems, the Uri for
which is nested within the {@link android.provider.ContactsContract.RawContacts}
directory to which the stream items belong. Each social stream table includes
several columns for metadata about each stream item, such as an icon
representing the source (an avatar), a label for the item, the primary text
content, comments about the item (such as responses from other people), and
more. Photos associated with a stream are stored in another table, defined by
-{@link android.provider.ContactsContract.StreamItemPhotos}, which is available
-as a sub-directory of the {@link android.provider.ContactsContract.StreamItems}
+android.provider.ContactsContract.StreamItemPhotos, which is available
+as a sub-directory of the android.provider.ContactsContract.StreamItems
Uri.</p>
-<p>See {@link android.provider.ContactsContract.StreamItems} and
-{@link android.provider.ContactsContract.StreamItemPhotos} for more information.</p>
+<p>See android.provider.ContactsContract.StreamItems and
+android.provider.ContactsContract.StreamItemPhotos for more information.</p>
<p>To read or write social stream items for a contact, an application must
request permission from the user by declaring <code><uses-permission
@@ -272,8 +272,8 @@
<p>The following are new permissions:</p>
<ul>
-<li>{@link android.Manifest.permission#READ_SOCIAL_STREAM} and
-{@link android.Manifest.permission#WRITE_SOCIAL_STREAM}: Allow a sync
+<li>android.Manifest.permission#READ_SOCIAL_STREAM and
+android.Manifest.permission#WRITE_SOCIAL_STREAM: Allow a sync
adapter to read and write social stream data to a contact in the shared
Contacts Provider.</li>
</ul>
diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd
index 6c4ccb4..cc1d1c7 100644
--- a/docs/html/about/versions/android-4.0.jd
+++ b/docs/html/about/versions/android-4.0.jd
@@ -108,9 +108,9 @@
the table at {@link android.provider.ContactsContract.Profile#CONTENT_RAW_CONTACTS_URI}. Raw
contacts in this table are then aggregated into the single user-visible profile labeled "Me".</p>
-<p>Adding a new raw contact for the profile requires the {@link
-android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile
-table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However,
+<p>Adding a new raw contact for the profile requires the
+android.Manifest.permission#WRITE_PROFILE permission. Likewise, in order to read from the profile
+table, you must request the android.Manifest.permission#READ_PROFILE permission. However,
most apps should not need to read the user profile, even when contributing data to the
profile. Reading the user profile is a sensitive permission and you should expect users to be
skeptical of apps that request it.</p>
@@ -1638,9 +1638,9 @@
android.service.textservice.SpellCheckerService} must require this permission for itself.</li>
<li>{@link android.Manifest.permission#BIND_VPN_SERVICE}: A service that implements {@link
android.net.VpnService} must require this permission for itself.</li>
-<li>{@link android.Manifest.permission#READ_PROFILE}: Provides read access to the {@link
+<li>android.Manifest.permission#READ_PROFILE: Provides read access to the {@link
android.provider.ContactsContract.Profile} provider.</li>
-<li>{@link android.Manifest.permission#WRITE_PROFILE}: Provides write access to the {@link
+<li>android.Manifest.permission#WRITE_PROFILE: Provides write access to the {@link
android.provider.ContactsContract.Profile} provider.</li>
</ul>
diff --git a/docs/html/about/versions/android-4.1.jd b/docs/html/about/versions/android-4.1.jd
index 76b90ac..f8770fa 100644
--- a/docs/html/about/versions/android-4.1.jd
+++ b/docs/html/about/versions/android-4.1.jd
@@ -871,7 +871,7 @@
automatically get read access as well. There is a new developer option to turn on read access
restriction, for developers to test their applications against how Android will behave in the
future.</dd>
- <dt>{@link android.Manifest.permission#READ_USER_DICTIONARY}</dt>
+ <dt>android.Manifest.permission.READ_USER_DICTIONARY</dt>
<dd>Allows an application to read the user dictionary. This should only be required by an
IME, or a dictionary editor like the Settings app.</dd>
<dt>{@link android.Manifest.permission#READ_CALL_LOG}</dt>
@@ -879,7 +879,7 @@
incoming and outgoing calls.</dd>
<dt>{@link android.Manifest.permission#WRITE_CALL_LOG}</dt>
<dd>Allows an application to modify the system's call log stored on your phone</dd>
- <dt>{@link android.Manifest.permission#WRITE_USER_DICTIONARY}</dt>
+ <dt>android.Manifest.permission.WRITE_USER_DICTIONARY</dt>
<dd>Allows an application to write to the user's word dictionary.</dd>
</dl>
diff --git a/docs/html/distribute/googleplay/about.jd b/docs/html/distribute/googleplay/about.jd
index 2652046..543d7d3 100644
--- a/docs/html/distribute/googleplay/about.jd
+++ b/docs/html/distribute/googleplay/about.jd
@@ -1,7 +1,7 @@
page.title=The Google Play Opportunity
meta.tags="visibility, growth, distributing"
page.tags="play, apps, distributing, publishing"
-page.metaDescription=Billons of downloads a month and growing. Get your apps in front of users at Google's scale.
+page.metaDescription=Billions of downloads a month and growing. Get your apps in front of users at Google's scale.
page.image=images/cards/google-play_2x.png
@jd:body
diff --git a/docs/html/distribute/googleplay/families/about.jd b/docs/html/distribute/googleplay/families/about.jd
index bec9b6a..9b85c9a 100644
--- a/docs/html/distribute/googleplay/families/about.jd
+++ b/docs/html/distribute/googleplay/families/about.jd
@@ -50,7 +50,7 @@
Designed for Families expands the visibility of your family content on Google
Play, helping parents easily find your family-friendly apps and games
throughout the store. And new features create a trusted environment that
- empowers parents to make informed desicions and engage with your content.
+ empowers parents to make informed decisions and engage with your content.
</p>
<h3>
Search
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd
index 3d1935a..e3f1d9e 100644
--- a/docs/html/guide/topics/graphics/hardware-accel.jd
+++ b/docs/html/guide/topics/graphics/hardware-accel.jd
@@ -284,7 +284,7 @@
</tr>
<tr>
<td class="label_neg">drawPicture()</td>
- <td class="value_neg">✗</td>
+ <td class="value_neg">23</td>
</tr>
<tr>
<td class="label_pos">drawPosText()</td>
diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd
index 9394114..bb93a70 100644
--- a/docs/html/guide/topics/manifest/uses-permission-element.jd
+++ b/docs/html/guide/topics/manifest/uses-permission-element.jd
@@ -81,6 +81,7 @@
</pre>
<p>This way, beginning with API level 19, the system will no longer grant your app the
{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
+<p>This attribute was added in API level 19.</p>
</dd>
</dl></dd>
diff --git a/docs/html/guide/topics/providers/contacts-provider.jd b/docs/html/guide/topics/providers/contacts-provider.jd
index e3b998a..2b14558 100644
--- a/docs/html/guide/topics/providers/contacts-provider.jd
+++ b/docs/html/guide/topics/providers/contacts-provider.jd
@@ -57,7 +57,7 @@
<li>{@link android.provider.ContactsContract.Contacts}</li>
<li>{@link android.provider.ContactsContract.RawContacts}</li>
<li>{@link android.provider.ContactsContract.Data}</li>
- <li>{@link android.provider.ContactsContract.StreamItems}</li>
+ <li>android.provider.ContactsContract.StreamItems</li>
</ol>
<h2>Related Samples</h2>
<ol>
@@ -606,13 +606,13 @@
Access to the user profile requires special permissions. In addition to the
{@link android.Manifest.permission#READ_CONTACTS} and
{@link android.Manifest.permission#WRITE_CONTACTS} permissions needed to read and write, access
- to the user profile requires the {@link android.Manifest.permission#READ_PROFILE} and
- {@link android.Manifest.permission#WRITE_PROFILE} permissions for read and write access,
+ to the user profile requires the android.Manifest.permission#READ_PROFILE and
+ android.Manifest.permission#WRITE_PROFILE permissions for read and write access,
respectively.
</p>
<p>
Remember that you should consider a user's profile to be sensitive. The permission
- {@link android.Manifest.permission#READ_PROFILE} allows you to access the device user's
+ android.Manifest.permission#READ_PROFILE allows you to access the device user's
personally-identifying data. Make sure to tell the user why
you need user profile access permissions in the description of your application.
</p>
@@ -1826,8 +1826,8 @@
</dl>
<h2 id="SocialStream">Social Stream Data</h2>
<p>
- The {@link android.provider.ContactsContract.StreamItems} and
- {@link android.provider.ContactsContract.StreamItemPhotos} tables
+ The android.provider.ContactsContract.StreamItems and
+ android.provider.ContactsContract.StreamItemPhotos tables
manage incoming data from social networks. You can write a sync adapter that adds stream data
from your own network to these tables, or you can read stream data from these tables and
display it in your own application, or both. With these features, your social networking
@@ -1836,7 +1836,7 @@
<h3 id="StreamText">Social stream text</h3>
<p>
Stream items are always associated with a raw contact. The
- {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} links to the
+ android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID links to the
<code>_ID</code> value for the raw contact. The account type and account name of the raw
contact are also stored in the stream item row.
</p>
@@ -1845,14 +1845,14 @@
</p>
<dl>
<dt>
- {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE}
+ android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
</dt>
<dd>
<strong>Required.</strong> The user's account type for the raw contact associated with this
stream item. Remember to set this value when you insert a stream item.
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME}
+ android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
</dt>
<dd>
<strong>Required.</strong> The user's account name for the raw contact associated with this
@@ -1866,30 +1866,30 @@
insert a stream item:
<ul>
<li>
- {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: The
- {@link android.provider.BaseColumns#_ID} value of the contact that this stream
+ android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: The
+ android.provider.BaseColumns#_ID value of the contact that this stream
item is associated with.
</li>
<li>
- {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: The
- {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} value of the
+ android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: The
+ android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY value of the
contact this stream item is associated with.
</li>
<li>
- {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: The
- {@link android.provider.BaseColumns#_ID} value of the raw contact that this stream
+ android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: The
+ android.provider.BaseColumns#_ID value of the raw contact that this stream
item is associated with.
</li>
</ul>
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemsColumns#COMMENTS}
+ android.provider.ContactsContract.StreamItemsColumns#COMMENTS
</dt>
<dd>
Optional. Stores summary information that you can display at the beginning of a stream item.
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemsColumns#TEXT}
+ android.provider.ContactsContract.StreamItemsColumns#TEXT
</dt>
<dd>
The text of the stream item, either the content that was posted by the source of the item,
@@ -1899,7 +1899,7 @@
ellipsize long content, but it will try to avoid breaking tags.
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}
+ android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
</dt>
<dd>
A text string containing the time the stream item was inserted or updated, in the form
@@ -1910,42 +1910,42 @@
</dl>
<p>
To display identifying information for your stream items, use the
- {@link android.provider.ContactsContract.StreamItemsColumns#RES_ICON},
- {@link android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, and
- {@link android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} to link to resources
+ android.provider.ContactsContract.StreamItemsColumns#RES_ICON,
+ android.provider.ContactsContract.StreamItemsColumns#RES_LABEL, and
+ android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE to link to resources
in your application.
</p>
<p>
- The {@link android.provider.ContactsContract.StreamItems} table also contains the columns
- {@link android.provider.ContactsContract.StreamItemsColumns#SYNC1} through
- {@link android.provider.ContactsContract.StreamItemsColumns#SYNC4} for the exclusive use of
+ The android.provider.ContactsContract.StreamItems table also contains the columns
+ android.provider.ContactsContract.StreamItemsColumns#SYNC1 through
+ android.provider.ContactsContract.StreamItemsColumns#SYNC4 for the exclusive use of
sync adapters.
</p>
<h3 id="StreamPhotos">Social stream photos</h3>
<p>
- The {@link android.provider.ContactsContract.StreamItemPhotos} table stores photos associated
+ The android.provider.ContactsContract.StreamItemPhotos table stores photos associated
with a stream item. The table's
- {@link android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} column
+ android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID column
links to values in the {@link android.provider.BaseColumns#_ID} column of
- {@link android.provider.ContactsContract.StreamItems} table. Photo references are stored in the
+ android.provider.ContactsContract.StreamItems table. Photo references are stored in the
table in these columns:
</p>
<dl>
<dt>
- {@link android.provider.ContactsContract.StreamItemPhotos#PHOTO} column (a BLOB).
+ android.provider.ContactsContract.StreamItemPhotos#PHOTO column (a BLOB).
</dt>
<dd>
A binary representation of the photo, resized by the provider for storage and display.
This column is available for backwards compatibility with previous versions of the Contacts
Provider that used it for storing photos. However, in the current version
you should not use this column to store photos. Instead, use
- either {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} or
- {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} (both of
+ either android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID or
+ android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI (both of
which are described in the following points) to store photos in a file. This column now
contains a thumbnail of the photo, which is available for reading.
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID}
+ android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID
</dt>
<dd>
A numeric identifier of a photo for a raw contact. Append this value to the constant
@@ -1955,7 +1955,7 @@
openAssetFileDescriptor()} to get a handle to the photo file.
</dd>
<dt>
- {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}
+ android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
</dt>
<dd>
A content URI pointing directly to the photo file for the photo represented by this row.
@@ -1970,27 +1970,27 @@
<ul>
<li>
These tables require additional access permissions. To read from them, your application
- must have the permission {@link android.Manifest.permission#READ_SOCIAL_STREAM}. To
+ must have the permission android.Manifest.permission#READ_SOCIAL_STREAM. To
modify them, your application must have the permission
- {@link android.Manifest.permission#WRITE_SOCIAL_STREAM}.
+ android.Manifest.permission#WRITE_SOCIAL_STREAM.
</li>
<li>
- For the {@link android.provider.ContactsContract.StreamItems} table, the number of rows
+ For the android.provider.ContactsContract.StreamItems table, the number of rows
stored for each raw contact is limited. Once this limit is reached,
the Contacts Provider makes space for new stream item rows by automatically deleting
the rows having the oldest
- {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}. To get the
+ android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP. To get the
limit, issue a query to the content URI
- {@link android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}. You can leave
+ android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI. You can leave
all the arguments other than the content URI set to <code>null</code>. The query
returns a Cursor containing a single row, with the single column
- {@link android.provider.ContactsContract.StreamItems#MAX_ITEMS}.
+ android.provider.ContactsContract.StreamItems#MAX_ITEMS.
</li>
</ul>
<p>
- The class {@link android.provider.ContactsContract.StreamItems.StreamItemPhotos} defines a
- sub-table of {@link android.provider.ContactsContract.StreamItemPhotos} containing the photo
+ The class android.provider.ContactsContract.StreamItems.StreamItemPhotos defines a
+ sub-table of android.provider.ContactsContract.StreamItemPhotos containing the photo
rows for a single stream item.
</p>
<h3 id="SocialStreamInteraction">Social stream interactions</h3>
@@ -2003,8 +2003,8 @@
<li>
By syncing your social networking service to the Contacts Provider with a sync
adapter, you can retrieve recent activity for a user's contacts and store it in
- the {@link android.provider.ContactsContract.StreamItems} and
- {@link android.provider.ContactsContract.StreamItemPhotos} tables for later use.
+ the android.provider.ContactsContract.StreamItems and
+ android.provider.ContactsContract.StreamItemPhotos tables for later use.
</li>
<li>
Besides regular synchronization, you can trigger your sync adapter to retrieve
@@ -2356,6 +2356,6 @@
</p>
<p>
Social stream data for a person may also include photos. These are stored in the
- {@link android.provider.ContactsContract.StreamItemPhotos} table, which is described in more
+ android.provider.ContactsContract.StreamItemPhotos table, which is described in more
detail in the section <a href="#StreamPhotos">Social stream photos</a>.
</p>
diff --git a/docs/html/images/distribute/hero-IO15-google-play.jpg b/docs/html/images/distribute/hero-IO15-google-play.jpg
new file mode 100644
index 0000000..3bfff96
--- /dev/null
+++ b/docs/html/images/distribute/hero-IO15-google-play.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-IO15-growing-games.jpg b/docs/html/images/distribute/hero-IO15-growing-games.jpg
new file mode 100644
index 0000000..c08bd71
--- /dev/null
+++ b/docs/html/images/distribute/hero-IO15-growing-games.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-family-discovery.jpg b/docs/html/images/distribute/hero-family-discovery.jpg
new file mode 100644
index 0000000..7ee26b5
--- /dev/null
+++ b/docs/html/images/distribute/hero-family-discovery.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-family.jpg b/docs/html/images/distribute/hero-family.jpg
deleted file mode 100644
index 6e467a5..0000000
--- a/docs/html/images/distribute/hero-family.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/distribute/hero-shifty-jelly.jpg b/docs/html/images/distribute/hero-shifty-jelly.jpg
new file mode 100644
index 0000000..4a2e986
--- /dev/null
+++ b/docs/html/images/distribute/hero-shifty-jelly.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-store-listing-experience.jpg b/docs/html/images/distribute/hero-store-listing-experience.jpg
new file mode 100644
index 0000000..5b00b51
--- /dev/null
+++ b/docs/html/images/distribute/hero-store-listing-experience.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-the-hunt.jpg b/docs/html/images/distribute/hero-the-hunt.jpg
new file mode 100644
index 0000000..ad6fd06
--- /dev/null
+++ b/docs/html/images/distribute/hero-the-hunt.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-trello.jpg b/docs/html/images/distribute/hero-trello.jpg
new file mode 100644
index 0000000..c89b32a
--- /dev/null
+++ b/docs/html/images/distribute/hero-trello.jpg
Binary files differ
diff --git a/docs/html/images/distribute/hero-wooga.jpg b/docs/html/images/distribute/hero-wooga.jpg
new file mode 100644
index 0000000..ca796a8
--- /dev/null
+++ b/docs/html/images/distribute/hero-wooga.jpg
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index cd129d49..794494e 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -71,7 +71,7 @@
data-maxResults="3"></div>
</div></section>
-<div class="dac-hero-carousel" data-carousel-query="collection:distribute/landing/carousel">
+<div class="dac-hero-carousel" data-carousel-query="collection:index/secondary/carousel">
</div>
<section class="dac-section dac-gray"><div class="wrap">
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 86089e6..e677f64 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -13,6 +13,15 @@
"sdk/index.html"
]
},
+ "index/secondary/carousel": {
+ "title": "",
+ "resources": [
+ "http://www.youtube.com/watch?v=0r36OJaeMo4",
+ "http://www.youtube.com/watch?v=1Iw7Tg_afKk",
+ "http://www.youtube.com/watch?v=TieksFvD-7o",
+ "http://www.youtube.com/watch?v=MCoh4Pxs_ok"
+ ]
+ },
"index/multiscreen": {
"title": "",
"resources": [
@@ -175,10 +184,10 @@
"distribute/landing/carousel": {
"title": "",
"resources": [
- "http://www.youtube.com/watch?v=Pd49vTkvu0U",
- "http://www.youtube.com/watch?v=ekxABqJeRBc",
- "http://www.youtube.com/watch?v=MPnH7h12h0U",
- "http://www.youtube.com/watch?v=700gYRkhkLM"
+ "https://www.youtube.com/watch?v=QDM52bblwlg",
+ "https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
]
},
"distribute/landing/googleplay": {
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index 5b2468d..5dbca75 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -2914,7 +2914,7 @@
"tags": [],
"image":"http://i1.ytimg.com/vi/jQWB_-o1kz4/maxresdefault.jpg",
"lang":"en",
- "type":"about"
+ "type":"youtube"
},
{
"title":"App Configurations, Testing and Launchers",
@@ -2926,7 +2926,7 @@
"tags": [],
"image":"http://i1.ytimg.com/vi/39NkpWkaH8M/maxresdefault.jpg",
"lang":"en",
- "type":"about"
+ "type":"youtube"
},
{
"title":"Building an enterprise ready app",
@@ -2938,7 +2938,7 @@
"tags": [],
"image":"http://i1.ytimg.com/vi/dH41OutAMNM/maxresdefault.jpg",
"lang":"en",
- "type":"develop"
+ "type":"youtube"
},
{
"title":"Android for Work: Single Use Devices",
@@ -2950,7 +2950,7 @@
"tags": [],
"image":"http://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg",
"lang":"en",
- "type":"about"
+ "type":"youtube"
},
{
"title":"Discover YouTube cards",
@@ -3301,6 +3301,41 @@
"tags": [],
"image": "distribute/images/advertising.jpg",
"type": "distribute"
+ },
+ {
+ "url":"https://www.youtube.com/watch?v=QDM52bblwlg",
+ "image": "images/distribute/hero-family-discovery.jpg",
+ "title": "Introducing the new family discovery experience on Google Play",
+ "summary": "Help families create little moments on Google Play. Opt-in your apps now.",
+ "tags":["families","googleplay"],
+ "type":"youtube"
+ },
+ {
+ "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "image": "http://i1.ytimg.com/vi/wcjqBSei3a0/maxresdefault.jpg",
+ "title": "Developers connecting the world through Google Play",
+ "summary": "The mobile ecosystem is empowering developers to make good on the dream of connecting the world through technology to improve people's lives.",
+ "tags":["io15","googleplay"],
+ "keywords":["Google I/O 2015","io"],
+ "type":"youtube"
+ },
+ {
+ "url":"https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "image": "http://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg",
+ "title": "Store Listing Experiments for Google Play",
+ "summary": "Learn how to use Google Play’s new store listing optimization feature to get more installs of your app, and how to test different graphics and text to find out which options perform the best. ",
+ "tags":["io15","googleplay","store listing"],
+ "tags":["google i/o","google play","store listing"],
+ "type":"youtube"
+ },
+ {
+ "url":"https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "image": "http://i1.ytimg.com/vi/jyO3-rF4Mu0/maxresdefault.jpg",
+ "title": "Growing games with Google",
+ "summary": "The games industry has never been more promising and full of opportunities. This talk covers how Google is helping developers across a broad range of existing and emerging platforms.",
+ "tags":["io15","android", "googleplay","games"],
+ "keywords":["Google I/O","google play","games"],
+ "type":"youtube"
}
]);
@@ -3310,41 +3345,85 @@
"heroColor": "#263238",
"heroInvert": true,
"title": "Android 5.0 Lollipop",
- "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new Material design interface, and much more."
- },
- "distribute/googleplay/families/about.html": {
- "image": "images/distribute/hero-family.jpg",
- "title": "Designed for Families",
- "summary": "Introducing a new Google Play section to promote family friendly apps. Your apps in the program can benefit from enhanced discoverability in addition to maintaining their existing categories, rankings, and reviews elsewhere on the Google Play store."
+ "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new naterial design interface, and much more.",
},
"http://www.youtube.com/watch?v=Pd49vTkvu0U": {
"url":"http://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
"image": "images/distribute/hero-jelly-button.jpg",
"title": "How Jelly Button Games are growing globally through data",
- "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery."
+ "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery.",
},
"http://www.youtube.com/watch?v=700gYRkhkLM": {
"url":"http://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
"image": "images/distribute/hero-outfit7.jpg",
"title": "Outfit7 — Building an entertainment company with Google",
- "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories...."
+ "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories....",
},
"http://www.youtube.com/watch?v=MPnH7h12h0U": {
"url":"http://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
"image": "images/distribute/hero-haystack.jpg",
- "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen."
+ "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen.",
},
"http://www.youtube.com/watch?v=ekxABqJeRBc": {
"url":"http://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
"image": "images/distribute/hero-ginlemon.jpg",
"title": "How GinLemon is breaking through with Google Play",
- "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy."
+ "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy.",
},
"distribute/googleplay/guide.html": {
"heroColor": "#fcb94e",
"image": "images/distribute/hero-g-play-guidebooks_2x.png",
- "title": "Finding Success on Google Play",
+ "title": "Finding success on Google Play",
"summary": "We’ve created a downloadable guide to help you find success with your app or game business on Google Play. In it, you’ll find features, tips, and best practices to help you build an effective strategy.",
- "tags": []
+ },
+ "http://www.youtube.com/watch?v=0r36OJaeMo4": {
+ "url":"http://www.youtube.com/watch?v=0r36OJaeMo4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
+ "image": "images/distribute/hero-shifty-jelly.jpg",
+ "title": "Shifty Jelly — building a number 1 podcast app",
+ "summary": "Shifty Jelly is an Adelaide based mobile development company that has seen great success building Pocket Casts, a premium podcast manager app.",
+ },
+ "http://www.youtube.com/watch?v=1Iw7Tg_afKk": {
+ "image": "images/distribute/hero-wooga.jpg",
+ "url":"http://www.youtube.com/watch?v=1Iw7Tg_afKk&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
+ "title": "Wooga’s fast iterations on Google Play",
+ "summary": "The speed at which Wooga is able to iterate its live and under development games with the Android and Google Play tools has been key to delivering hits such as Diamond Dash, Jelly Splash, and Agent Alice.",
+ },
+ "http://www.youtube.com/watch?v=TieksFvD-7o": {
+ "url":"http://www.youtube.com/watch?v=TieksFvD-7o&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
+ "image": "images/distribute/hero-trello.jpg",
+ "title": "Trello lifts engagement by double digits with material design",
+ "summary": "Trello recently redesigned their collaborative planning app using the material design guidelines, and their efforts paid off.",
+ },
+ "http://www.youtube.com/watch?v=MCoh4Pxs_ok": {
+ "url":"http://www.youtube.com/watch?v=MCoh4Pxs_ok&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c",
+ "image": "images/distribute/hero-the-hunt.jpg",
+ "title": "The Hunt — growing engagement with material design and Google Play",
+ "summary": "Material design has helped The Hunt to enhance engagement in their style advice and product discovery app. ",
+ },
+ "https://www.youtube.com/watch?v=QDM52bblwlg": {
+ "url":"distribute/googleplay/families/about.html",
+ "image": "images/distribute/hero-family-discovery.jpg",
+ "title": "Designed for families",
+ "summary": "Introducing the new family discovery experience in Google Play. Your apps can benefit from enhanced discoverability and maintain their existing categories, rankings, and reviews elsewhere in the store. Opt-in your apps today.",
+ "type":"distribute",
+ },
+ "https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": {
+ "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS",
+ "image": "images/distribute/hero-IO15-google-play.jpg",
+ "title": "Connecting the world through Google Play",
+ "tags":["io15"],
+ "summary": "In this this Google I/O talk, hear how the mobile ecosystem is empowering developers to connect the world through technology and improve people's lives.",
+ },
+ "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": {
+ "image": "images/distribute/hero-store-listing-experience.jpg",
+ "title": "Using Google Play store listing experiments",
+ "tags":["io15"],
+ "summary": "Learn how to use Google Play store listing experiments to get more installs in this Google I/O talk. Test different graphics and text to find out which options perform the best. ",
+ },
+ "https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": {
+ "image": "images/distribute/hero-IO15-growing-games.jpg",
+ "title": "Growing games with Google",
+ "tags":["io15"],
+ "summary": "The games industry has never been more promising and full of opportunities. This talk from Google I/O 2015 covers how Google is helping developers across a broad range of existing and emerging platforms.",
}
-};
+};
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index 39272b9..0e55089 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -135,8 +135,8 @@
* properly and are highly discouraged.
*
* <p>
- * <strong>Note:</strong> a picture created from an input stream cannot be
- * replayed on a hardware accelerated canvas.
+ * <strong>Note:</strong> Prior to API level 23 a picture created from an
+ * input stream cannot be replayed on a hardware accelerated canvas.
*
* @see #writeToStream(java.io.OutputStream)
* @deprecated The recommended alternative is to not use writeToStream and
@@ -155,8 +155,8 @@
* there is no guarantee that the Picture can be successfully reconstructed.
*
* <p>
- * <strong>Note:</strong> a picture created from an input stream cannot be
- * replayed on a hardware accelerated canvas.
+ * <strong>Note:</strong> Prior to API level 23 a picture created from an
+ * input stream cannot be replayed on a hardware accelerated canvas.
*
* @see #createFromStream(java.io.InputStream)
* @deprecated The recommended alternative is to draw the picture into a
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index f059727..fcd7f63 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -362,11 +362,6 @@
invalidateSelf();
}
- @Override
- public boolean isDither() {
- return mBitmapState.mPaint.isDither();
- }
-
/**
* Indicates the repeat behavior of this drawable on the X axis.
*
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 5e62aea..32af59a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -269,30 +269,29 @@
}
/**
- * Set to true to have the drawable dither its colors when drawn to a device
- * with fewer than 8-bits per color component. This can improve the look on
- * those devices, but can also slow down the drawing a little.
+ * Set to true to have the drawable dither its colors when drawn to a
+ * device with fewer than 8-bits per color component.
+ *
+ * @see android.graphics.Paint#setDither(boolean);
+ * @deprecated This property is ignored.
*/
+ @Deprecated
public void setDither(boolean dither) {}
/**
- * @return whether this drawable dithers its colors
- * @see #setDither(boolean)
- */
- public boolean isDither() {
- return false;
- }
-
- /**
- * Set to true to have the drawable filter its bitmap when scaled or rotated
- * (for drawables that use bitmaps). If the drawable does not use bitmaps,
- * this call is ignored. This can improve the look when scaled or rotated,
- * but also slows down the drawing.
+ * Set to true to have the drawable filter its bitmaps with bilinear
+ * sampling when they are scaled or rotated.
+ *
+ * <p>This can improve appearance when bitmaps are rotated. If the drawable
+ * does not use bitmaps, this call is ignored.</p>
+ *
+ * @see #isFilterBitmap()
+ * @see android.graphics.Paint#setFilterBitmap(boolean);
*/
public void setFilterBitmap(boolean filter) {}
/**
- * @return whether this drawable filters its bitmap
+ * @return whether this drawable filters its bitmaps
* @see #setFilterBitmap(boolean)
*/
public boolean isFilterBitmap() {
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1759f53..b344b86 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -167,11 +167,6 @@
}
@Override
- public boolean isDither() {
- return mDrawableContainerState.mDither;
- }
-
- @Override
public void setColorFilter(ColorFilter colorFilter) {
mDrawableContainerState.mHasColorFilter = true;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 626991d..a11b2cd 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -826,11 +826,6 @@
}
@Override
- public boolean isDither() {
- return mGradientState.mDither;
- }
-
- @Override
public ColorFilter getColorFilter() {
return mColorFilter;
}
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 425225c..7c9b30b 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -116,6 +116,10 @@
return (Bitmap) mObj1;
}
+ private void setBitmap(Bitmap b) {
+ mObj1 = b;
+ }
+
/**
* @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon.
* @hide
@@ -367,6 +371,16 @@
}
/**
+ * Puts the memory used by this instance into Ashmem memory, if possible.
+ * @hide
+ */
+ public void convertToAshmem() {
+ if (mType == TYPE_BITMAP && getBitmap().isMutable()) {
+ setBitmap(getBitmap().createAshmemBitmap());
+ }
+ }
+
+ /**
* Writes a serialized version of an Icon to the specified stream.
*
* @param stream The stream on which to serialize the Icon.
@@ -486,7 +500,7 @@
throw new IllegalArgumentException("Bitmap must not be null.");
}
final Icon rep = new Icon(TYPE_BITMAP);
- rep.mObj1 = bits;
+ rep.setBitmap(bits);
return rep;
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 90891f6..8373c7f 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1248,16 +1248,6 @@
}
@Override
- public boolean isDither() {
- final Drawable dr = getFirstNonNullDrawable();
- if (dr != null) {
- return dr.isDither();
- } else {
- return super.isDither();
- }
- }
-
- @Override
public void setAlpha(int alpha) {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index adf53e3..152fe6a 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -374,11 +374,6 @@
}
@Override
- public boolean isDither() {
- return mPaint == null ? DEFAULT_DITHER : mPaint.isDither();
- }
-
- @Override
public void setAutoMirrored(boolean mirrored) {
mNinePatchState.mAutoMirrored = mirrored;
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index a669d3c..30b588e 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -328,11 +328,6 @@
}
@Override
- public boolean isDither() {
- return mShapeState.mPaint.isDither();
- }
-
- @Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
updateShape();
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
index 250bad7..515be1d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
@@ -113,7 +113,7 @@
return result;
} else {
throw new InvalidKeySpecException(
- "Obtaining RSAPublicKeySpec not supported for " + key.getAlgorithm() + " "
+ "Obtaining ECPublicKeySpec not supported for " + key.getAlgorithm() + " "
+ ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public")
+ " key");
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 688936c..66509e2 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -31,7 +31,6 @@
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
-import java.util.Date;
import javax.crypto.KeyGeneratorSpi;
import javax.crypto.SecretKey;
@@ -278,15 +277,11 @@
KeymasterUtils.addUserAuthArgs(args,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds());
- args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- (spec.getKeyValidityStart() != null)
- ? spec.getKeyValidityStart() : new Date(0));
- args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- (spec.getKeyValidityForOriginationEnd() != null)
- ? spec.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE));
- args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- (spec.getKeyValidityForConsumptionEnd() != null)
- ? spec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE));
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
+ spec.getKeyValidityForOriginationEnd());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
+ spec.getKeyValidityForConsumptionEnd());
if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!spec.isRandomizedEncryptionRequired())) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 2055cdb..ff265cf 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -415,15 +415,11 @@
KeymasterUtils.addUserAuthArgs(args,
mSpec.isUserAuthenticationRequired(),
mSpec.getUserAuthenticationValidityDurationSeconds());
- args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- (mSpec.getKeyValidityStart() != null)
- ? mSpec.getKeyValidityStart() : new Date(0));
- args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- (mSpec.getKeyValidityForOriginationEnd() != null)
- ? mSpec.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE));
- args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- (mSpec.getKeyValidityForConsumptionEnd() != null)
- ? mSpec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE));
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
+ mSpec.getKeyValidityForOriginationEnd());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
+ mSpec.getKeyValidityForConsumptionEnd());
addAlgorithmSpecificParameters(args);
byte[] additionalEntropy =
@@ -515,15 +511,23 @@
return generateSelfSignedCertificateWithFakeSignature(publicKey);
} else {
// Key can be used to sign a certificate
- return generateSelfSignedCertificateWithValidSignature(
- privateKey, publicKey, signatureAlgorithm);
+ try {
+ return generateSelfSignedCertificateWithValidSignature(
+ privateKey, publicKey, signatureAlgorithm);
+ } catch (Exception e) {
+ // Failed to generate the self-signed certificate with valid signature. Fall back
+ // to generating a self-signed certificate with a fake signature. This is done for
+ // all exception types because we prefer key pair generation to succeed and end up
+ // producing a self-signed certificate with an invalid signature to key pair
+ // generation failing.
+ return generateSelfSignedCertificateWithFakeSignature(publicKey);
+ }
}
}
@SuppressWarnings("deprecation")
private X509Certificate generateSelfSignedCertificateWithValidSignature(
- PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm)
- throws Exception {
+ PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm) throws Exception {
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setPublicKey(publicKey);
certGen.setSerialNumber(mSpec.getCertificateSerialNumber());
@@ -624,9 +628,8 @@
// Constraints:
// 1. Key must be authorized for signing without user authentication.
// 2. Signature digest must be one of key's authorized digests.
- // 3. For RSA keys, the digest output size must not exceed modulus size minus space needed
- // for RSA PKCS#1 signature padding (about 29 bytes: minimum 10 bytes of padding + 15--19
- // bytes overhead for encoding digest OID and digest value in DER).
+ // 3. For RSA keys, the digest output size must not exceed modulus size minus space overhead
+ // of RSA PKCS#1 signature padding scheme (about 30 bytes).
// 4. For EC keys, the there is no point in using a digest whose output size is longer than
// key/field size because the digest will be truncated to that size.
@@ -727,10 +730,12 @@
spec.getDigests(),
AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());
- // The amount of space available for the digest is less than modulus size because
- // padding must be at least 10 bytes long, and then there's also the 15--19
- // bytes overhead for encoding digest OID and digest value in DER.
- int maxDigestOutputSizeBits = keySizeBits - 29 * 8;
+ // The amount of space available for the digest is less than modulus size by about
+ // 30 bytes because padding must be at least 11 bytes long (00 || 01 || PS || 00,
+ // where PS must be at least 8 bytes long), and then there's also the 15--19 bytes
+ // overhead (depending the on chosen digest) for encoding digest OID and digest
+ // value in DER.
+ int maxDigestOutputSizeBits = keySizeBits - 30 * 8;
int bestKeymasterDigest = -1;
int bestDigestOutputSizeBits = -1;
for (int keymasterDigest : availableKeymasterDigests) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 8b00821..7887923 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -147,21 +147,10 @@
}
Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
- if ((keyValidityStart != null) && (keyValidityStart.getTime() <= 0)) {
- keyValidityStart = null;
- }
Date keyValidityForOriginationEnd =
keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
- if ((keyValidityForOriginationEnd != null)
- && (keyValidityForOriginationEnd.getTime() == Long.MAX_VALUE)) {
- keyValidityForOriginationEnd = null;
- }
Date keyValidityForConsumptionEnd =
keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
- if ((keyValidityForConsumptionEnd != null)
- && (keyValidityForConsumptionEnd.getTime() == Long.MAX_VALUE)) {
- keyValidityForConsumptionEnd = null;
- }
boolean userAuthenticationRequired =
!keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
int userAuthenticationValidityDurationSeconds =
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 5fb589e..084e30e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -435,17 +435,12 @@
KeymasterUtils.addUserAuthArgs(importArgs,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds());
- importArgs.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- (spec.getKeyValidityStart() != null)
- ? spec.getKeyValidityStart() : new Date(0));
- importArgs.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- (spec.getKeyValidityForOriginationEnd() != null)
- ? spec.getKeyValidityForOriginationEnd()
- : new Date(Long.MAX_VALUE));
- importArgs.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- (spec.getKeyValidityForConsumptionEnd() != null)
- ? spec.getKeyValidityForConsumptionEnd()
- : new Date(Long.MAX_VALUE));
+ importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
+ spec.getKeyValidityStart());
+ importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
+ spec.getKeyValidityForOriginationEnd());
+ importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
+ spec.getKeyValidityForConsumptionEnd());
} catch (IllegalArgumentException e) {
throw new KeyStoreException("Invalid parameter", e);
}
@@ -646,15 +641,11 @@
KeymasterUtils.addUserAuthArgs(args,
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds());
- args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
- (params.getKeyValidityStart() != null)
- ? params.getKeyValidityStart() : new Date(0));
- args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
- (params.getKeyValidityForOriginationEnd() != null)
- ? params.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE));
- args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
- (params.getKeyValidityForConsumptionEnd() != null)
- ? params.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE));
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
+ params.getKeyValidityForOriginationEnd());
+ args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
+ params.getKeyValidityForConsumptionEnd());
if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!params.isRandomizedEncryptionRequired())) {
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 1732db9..919dd48 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -71,6 +71,8 @@
* <li>{@link KeyProperties#PURPOSE_SIGN},</li>
* <li>operation without requiring the user to be authenticated (see
* {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
+ * <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)}
+ * and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li>
* <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
* <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
* {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
@@ -634,11 +636,12 @@
/**
* Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which
- * the key can be used when signing/verifying. Attempts to use the key with any other digest
- * algorithm will be rejected.
+ * the key can be used. Attempts to use the key with any other digest algorithm will be
+ * rejected.
*
- * <p>This must be specified for keys which are used for signing/verification. For HMAC
- * keys, the set of digests defaults to the digest associated with the key algorithm (e.g.,
+ * <p>This must be specified for signing/verification keys and RSA encryption/decryption
+ * keys used with RSA OAEP padding scheme because these operations involve a digest. For
+ * HMAC keys, the default is the digest associated with the key algorithm (e.g.,
* {@code SHA-256} for key algorithm {@code HmacSHA256}).
*
* <p>For private keys used for TLS/SSL client or server authentication it is usually
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index b7a2a0b..5b4b3e7 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -417,12 +417,13 @@
/**
* Sets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the
- * key can be used when signing/verifying or generating MACs. Attempts to use the key with
- * any other digest algorithm will be rejected.
+ * key can be used. Attempts to use the key with any other digest algorithm will be
+ * rejected.
*
- * <p>For HMAC keys, the default is the digest algorithm specified in
- * {@link Key#getAlgorithm()}. For asymmetric signing keys the set of digest algorithms
- * must be specified.
+ * <p>This must be specified for signing/verification keys and RSA encryption/decryption
+ * keys used with RSA OAEP padding scheme because these operations involve a digest. For
+ * HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()} (e.g.,
+ * {@code SHA-256} for key algorithm {@code HmacSHA256}).
*
* <p>For private keys used for TLS/SSL client or server authentication it is usually
* necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 843c412..02a4877 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -135,6 +135,8 @@
}
void DisplayListCanvas::translate(float dx, float dy) {
+ if (dx == 0.0f && dy == 0.0f) return;
+
mHasDeferredTranslate = true;
mTranslateX += dx;
mTranslateY += dy;
@@ -143,11 +145,15 @@
}
void DisplayListCanvas::rotate(float degrees) {
+ if (degrees == 0.0f) return;
+
addStateOp(new (alloc()) RotateOp(degrees));
mState.rotate(degrees);
}
void DisplayListCanvas::scale(float sx, float sy) {
+ if (sx == 1.0f && sy == 1.0f) return;
+
addStateOp(new (alloc()) ScaleOp(sx, sy));
mState.scale(sx, sy);
}
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index d9b40ae..00add29 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -14,15 +14,13 @@
* limitations under the License.
*/
-#define LOG_TAG "OpenGLRenderer"
-#define ATRACE_TAG ATRACE_TAG_VIEW
-
#include "LayerCache.h"
#include "LayerRenderer.h"
#include "Matrix.h"
#include "Properties.h"
#include "Rect.h"
#include "renderstate/RenderState.h"
+#include "utils/GLUtils.h"
#include "utils/TraceUtils.h"
#include <ui/Rect.h>
@@ -238,8 +236,9 @@
layer->allocateTexture();
// This should only happen if we run out of memory
- if (glGetError() != GL_NO_ERROR) {
- ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height);
+ if (CC_UNLIKELY(GLUtils::dumpGLErrors())) {
+ LOG_ALWAYS_FATAL("Could not allocate texture for layer (fbo=%d %dx%d)",
+ fbo, width, height);
renderState.bindFramebuffer(previousFbo);
layer->decStrong(nullptr);
return nullptr;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index a323065..6cf66cd 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -419,12 +419,12 @@
bool SkiaCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
mCanvas->clipRect(rect, op);
- return mCanvas->isClipEmpty();
+ return !mCanvas->isClipEmpty();
}
bool SkiaCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
mCanvas->clipPath(*path, op);
- return mCanvas->isClipEmpty();
+ return !mCanvas->isClipEmpty();
}
bool SkiaCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
@@ -438,7 +438,7 @@
} else {
mCanvas->clipRect(SkRect::MakeEmpty(), op);
}
- return mCanvas->isClipEmpty();
+ return !mCanvas->isClipEmpty();
}
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp
index 9b298ca..55104de 100644
--- a/libs/hwui/utils/GLUtils.cpp
+++ b/libs/hwui/utils/GLUtils.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "OpenGLRenderer"
-
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -26,9 +24,11 @@
namespace android {
namespace uirenderer {
-void GLUtils::dumpGLErrors() {
+bool GLUtils::dumpGLErrors() {
+ bool errorObserved = false;
GLenum status = GL_NO_ERROR;
while ((status = glGetError()) != GL_NO_ERROR) {
+ errorObserved = true;
switch (status) {
case GL_INVALID_ENUM:
ALOGE("GL error: GL_INVALID_ENUM");
@@ -46,6 +46,7 @@
ALOGE("GL error: 0x%x", status);
}
}
+ return errorObserved;
}
}; // namespace uirenderer
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index 890e374..7020461 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -20,12 +20,11 @@
namespace uirenderer {
class GLUtils {
-private:
public:
/**
- * Print out any GL errors with ALOGE
+ * Print out any GL errors with ALOGE, returns true if any errors were found.
*/
- static void dumpGLErrors();
+ static bool dumpGLErrors();
}; // class GLUtils
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index b09f216..2c19324 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -892,7 +892,6 @@
* @param listener listener object that no longer needs location updates
* @throws IllegalArgumentException if listener is null
*/
- @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void removeUpdates(LocationListener listener) {
checkListener(listener);
String packageName = mContext.getPackageName();
@@ -1055,7 +1054,6 @@
* @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
* permission is not present
*/
- @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void removeProximityAlert(PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1083,7 +1081,6 @@
*
* @hide
*/
- @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void removeGeofence(Geofence fence, PendingIntent intent) {
checkPendingIntent(intent);
checkGeofence(fence);
@@ -1107,7 +1104,6 @@
*
* @hide
*/
- @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void removeAllGeofences(PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index 9609c35..d303a2e 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -150,6 +150,25 @@
/**
* High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
+ * <p>
+ * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to
+ * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just
+ * higher output frame rate and bit rate. Therefore, setting these profiles with
+ * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will
+ * produce high speed videos rather than slow motion videos that have different capture and
+ * output (playback) frame rates. To record slow motion videos, the application must set video
+ * output (playback) frame rate and bit rate appropriately via
+ * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate}
+ * based on the slow motion factor. If the application intends to do the video recording with
+ * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
+ * similarly according to this CamcorderProfile.
+ * </p>
+ *
+ * @see #videoBitRate
+ * @see #videoFrameRate
+ * @see MediaRecorder
+ * @see MediaCodec
+ * @see MediaFormat
*/
public static final int QUALITY_HIGH_SPEED_LOW = 2000;
@@ -212,11 +231,56 @@
/**
* The target video output bit rate in bits per second
+ * <p>
+ * This is the target recorded video output bit rate if the application configures the video
+ * recording via {@link MediaRecorder#setProfile} without specifying any other
+ * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
+ * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate
+ * where the video is recorded with. If the application intends to record slow motion videos
+ * with the high speed quality profiles, it must set a different video bit rate that is
+ * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate
+ * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if
+ * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps
+ * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to
+ * record 1/8 factor slow motion recording videos, the application must set 30fps via
+ * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion
+ * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in
+ * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output
+ * bit rate exceeds the encoder limit. If the application intends to do the video recording with
+ * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
+ * similarly according to this CamcorderProfile.
+ * </p>
+ *
+ * @see #videoFrameRate
+ * @see MediaRecorder
+ * @see MediaCodec
+ * @see MediaFormat
*/
public int videoBitRate;
/**
- * The target video frame rate in frames per second
+ * The target video frame rate in frames per second.
+ * <p>
+ * This is the target recorded video output frame rate per second if the application configures
+ * the video recording via {@link MediaRecorder#setProfile} without specifying any other
+ * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
+ * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate
+ * where the video is recorded and played back with. If the application intends to create slow
+ * motion use case with the high speed quality profiles, it must set a different video frame
+ * rate that is corresponding to the desired output (playback) frame rate via
+ * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P}
+ * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application
+ * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via
+ * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos
+ * with normal speed playback frame rate (240fps for above example). If the application intends
+ * to do the video recording with {@link MediaCodec} encoder, it must set each individual field
+ * of {@link MediaFormat} similarly according to this CamcorderProfile.
+ * </p>
+ *
+ * @see #videoBitRate
+ * @see MediaRecorder
+ * @see MediaCodec
+ * @see MediaFormat
*/
public int videoFrameRate;
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index da5f33e..7cd086e 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -710,7 +710,7 @@
public static final String COLUMN_LOCKED = "locked";
/**
- * The app badge icon of the app link template for this channel.
+ * The URI for the app badge icon of the app link template for this channel.
*
* <p>This small icon is overlaid at the bottom of the poster art specified by
* {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of
@@ -736,9 +736,10 @@
public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
/**
- * The poster art used as the background of the app link template for this channel.
+ * The URI for the poster art used as the background of the app link template for this
+ * channel.
*
- * <p>The data in the column must be a URL or a URI in one of the following formats:
+ * <p>The data in the column must be a URL, or a URI in one of the following formats:
*
* <ul>
* <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
@@ -1100,6 +1101,15 @@
/**
* The URI for the poster art of this TV program.
*
+ * <p>The data in the column must be a URL, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+ * </li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
* <p>Can be empty.
*
* <p>Type: TEXT
@@ -1109,6 +1119,19 @@
/**
* The URI for the thumbnail of this TV program.
*
+ * <p>The system can generate a thumbnail from the poster art if this column is not
+ * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
+ * just a scaled image of the poster art.
+ *
+ * <p>The data in the column must be a URL, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+ * </li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
* <p>Can be empty.
*
* <p>Type: TEXT
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 64333ad..003a274 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -272,7 +272,7 @@
/**
* Tunes to a given channel.
*
- * @param inputId The ID of TV input which will play the given channel.
+ * @param inputId The ID of the TV input for the given channel.
* @param channelUri The URI of a channel.
*/
public void tune(@NonNull String inputId, Uri channelUri) {
@@ -282,9 +282,9 @@
/**
* Tunes to a given channel.
*
- * @param inputId The ID of TV input which will play the given channel.
+ * @param inputId The ID of TV input for the given channel.
* @param channelUri The URI of a channel.
- * @param params Extra parameters which might be handled with the tune event.
+ * @param params Extra parameters.
* @hide
*/
@SystemApi
@@ -298,22 +298,26 @@
sMainTvView = new WeakReference<>(this);
}
}
- if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) {
+ if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
if (mSession != null) {
mSession.tune(channelUri, params);
} else {
- // Session is not created yet. Replace the channel which will be set once the
- // session is made.
+ // createSession() was called but the actual session for the given inputId has not
+ // yet been created. Just replace the existing tuning params in the callback with
+ // the new ones and tune later in onSessionCreated(). It is not necessary to create
+ // a new callback because this tuning request was made on the same inputId.
mSessionCallback.mChannelUri = channelUri;
mSessionCallback.mTuneParams = params;
}
} else {
resetInternal();
- // When createSession() is called multiple times before the callback is called,
- // only the callback of the last createSession() call will be actually called back.
- // The previous callbacks will be ignored. For the logic, mSessionCallback
- // is newly assigned for every createSession request and compared with
- // MySessionCreateCallback.this.
+ // In case createSession() is called multiple times across different inputId's before
+ // any session is created (e.g. when quickly tuning to a channel from input A and then
+ // to another channel from input B), only the callback for the last createSession()
+ // should be invoked. (The previous callbacks are simply ignored.) To do that, we create
+ // a new callback each time and keep mSessionCallback pointing to the last one. If
+ // MySessionCallback.this is different from mSessionCallback, we know that this callback
+ // is obsolete and should ignore it.
mSessionCallback = new MySessionCallback(inputId, channelUri, params);
if (mTvInputManager != null) {
mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
@@ -337,6 +341,7 @@
}
private void resetInternal() {
+ mSessionCallback = null;
mPendingAppPrivateCommands.clear();
if (mSession != null) {
setSessionSurface(null);
@@ -344,7 +349,6 @@
mUseRequestedSurfaceLayout = false;
mSession.release();
mSession = null;
- mSessionCallback = null;
resetSurfaceView();
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index fe148da..c541bca 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -186,6 +186,9 @@
}
if (!mState.restored) {
+ // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent
+ // talkback from reading aloud the default title, we clear it here.
+ setTitle("");
if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
final Uri rootUri = getIntent().getData();
new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor());
diff --git a/packages/Keyguard/res/values-ta-rIN/strings.xml b/packages/Keyguard/res/values-ta-rIN/strings.xml
index 43673ed..911611f 100644
--- a/packages/Keyguard/res/values-ta-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ta-rIN/strings.xml
@@ -115,16 +115,16 @@
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"சுயவிவரங்களுக்கு இடையே மாறும் போது, பின் தேவை."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"சுயவிவரங்களுக்கு இடையே மாறும் போது, கடவுச்சொல் தேவை."</string>
<plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
- <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. வடிவத்தை உறுதிப்படுத்தவும்.</item>
- <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. வடிவத்தை உறுதிப்படுத்தவும்.</item>
+ <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. வடிவத்தை உறுதிப்படுத்தவும்.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. வடிவத்தை உறுதிப்படுத்தவும்.</item>
</plurals>
<plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="2118758475374354849">
- <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. பின்னை உறுதிப்படுத்தவும்.</item>
- <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. பின்னை உறுதிப்படுத்தவும்.</item>
+ <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. பின்னை உறுதிப்படுத்தவும்.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. பின்னை உறுதிப்படுத்தவும்.</item>
</plurals>
<plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5132693663364913675">
- <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. கடவுச்சொல்லை உறுதிப்படுத்தவும்.</item>
- <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரத்திற்குச் சாதனம் திறக்கப்படவில்லை. கடவுச்சொல்லை உறுதிப்படுத்தவும்.</item>
+ <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. கடவுச்சொல்லை உறுதிப்படுத்தவும்.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> மணிநேரமாகச் சாதனம் திறக்கப்படவில்லை. கடவுச்சொல்லை உறுதிப்படுத்தவும்.</item>
</plurals>
<string name="fingerprint_not_recognized" msgid="2690661881608146617">"அறியப்படவில்லை"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index f4e4ea1..ef08e19 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -346,7 +346,7 @@
accessPoint.update(mLastInfo, mLastNetworkInfo);
}
- if (result.passpointNetwork) {
+ if (result.isPasspointNetwork()) {
WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
if (config != null) {
accessPoint.update(config);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 5137e1b..44b9d8b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -342,7 +342,7 @@
}
String name = values.getAsString(Settings.Secure.NAME);
- if (TextUtils.isEmpty(name)) {
+ if (!isKeyValid(name)) {
return null;
}
@@ -406,11 +406,10 @@
return 0;
}
- if (TextUtils.isEmpty(args.name)) {
+ if (!isKeyValid(args.name)) {
return 0;
}
-
switch (args.table) {
case TABLE_GLOBAL: {
final int userId = UserHandle.getCallingUserId();
@@ -446,10 +445,11 @@
return 0;
}
- String value = values.getAsString(Settings.Secure.VALUE);
- if (TextUtils.isEmpty(value)) {
+ String name = values.getAsString(Settings.Secure.NAME);
+ if (!isKeyValid(name)) {
return 0;
}
+ String value = values.getAsString(Settings.Secure.VALUE);
switch (args.table) {
case TABLE_GLOBAL: {
@@ -525,13 +525,20 @@
final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
do {
- pw.append("_id:").append(cursor.getString(idColumnIdx));
- pw.append(" name:").append(cursor.getString(nameColumnIdx));
- pw.append(" value:").append(cursor.getString(valueColumnIdx));
+ pw.append("_id:").append(toDumpString(cursor.getString(idColumnIdx)));
+ pw.append(" name:").append(toDumpString(cursor.getString(nameColumnIdx)));
+ pw.append(" value:").append(toDumpString(cursor.getString(valueColumnIdx)));
pw.println();
} while (cursor.moveToNext());
}
+ private static final String toDumpString(String s) {
+ if (s != null) {
+ return s;
+ }
+ return "{null}";
+ }
+
private void registerBroadcastReceivers() {
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_REMOVED);
@@ -897,16 +904,16 @@
private boolean mutateSystemSetting(String name, String value, int runAsUserId,
int operation) {
- // Make sure the caller can change the settings.
- enforceWritePermission(Manifest.permission.WRITE_SETTINGS);
+ // Check for permissions first.
+ hasPermissionsToMutateSystemSettings();
// Verify whether this operation is allowed for the calling package.
if (!isAppOpWriteSettingsAllowedForCallingPackage()) {
return false;
}
- // Enforce what the calling package can mutate in the system settings.
- enforceRestrictedSystemSettingsMutationForCallingPackageLocked(operation, name);
+ // Enforce what the calling package can mutate the system settings.
+ enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name);
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);
@@ -947,6 +954,28 @@
}
}
+ private boolean hasPermissionsToMutateSystemSettings() {
+ // Write secure settings is a more protected permission. If caller has it we are good.
+ if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+
+ // The write settings permission gates mutation of system settings.
+ if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SETTINGS)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+
+ // Excpet we let system apps change system settings without the permission.
+ PackageInfo packageInfo = getCallingPackageInfoOrThrow();
+ if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return true;
+ }
+
+ return false;
+ }
+
private void validateSystemSettingValue(String name, String value) {
Settings.System.Validator validator = Settings.System.VALIDATORS.get(name);
if (validator != null && !validator.validate(value)) {
@@ -993,7 +1022,7 @@
return userId;
}
- private void enforceRestrictedSystemSettingsMutationForCallingPackageLocked(int operation,
+ private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
String name) {
// System/root/shell can mutate whatever secure settings they want.
final int callingUid = Binder.getCallingUid();
@@ -1280,6 +1309,10 @@
cursor.addRow(values);
}
+ private static boolean isKeyValid(String key) {
+ return !(TextUtils.isEmpty(key) || SettingsState.isBinary(key));
+ }
+
private static final class Arguments {
private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS =
Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*");
@@ -1812,7 +1845,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 120;
+ private static final int SETTINGS_VERSION = 121;
private final int mUserId;
@@ -1940,6 +1973,10 @@
currentVersion = 120;
}
+ // Before 121, we used a different string encoding logic. We just bump the version
+ // here; SettingsState knows how to handle pre-version 120 files.
+ currentVersion = 121;
+
// vXXX: Add new settings above this point.
// Return the current version.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index a2adb15..95d7772 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -23,6 +23,7 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.AtomicFile;
+import android.util.Base64;
import android.util.Slog;
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
@@ -59,6 +60,8 @@
private static final String LOG_TAG = "SettingsState";
+ static final int SETTINGS_VERSOIN_NEW_ENCODING = 121;
+
private static final long WRITE_SETTINGS_DELAY_MILLIS = 200;
private static final long MAX_WRITE_SETTINGS_DELAY_MILLIS = 2000;
@@ -76,9 +79,19 @@
private static final String ATTR_VERSION = "version";
private static final String ATTR_ID = "id";
private static final String ATTR_NAME = "name";
+
+ /** Non-binary value will be written in this attribute. */
private static final String ATTR_VALUE = "value";
- private static final String NULL_VALUE = "null";
+ /**
+ * KXmlSerializer won't like some characters. We encode such characters in base64 and
+ * store in this attribute.
+ * NOTE: A null value will have NEITHER ATTR_VALUE nor ATTR_VALUE_BASE64.
+ */
+ private static final String ATTR_VALUE_BASE64 = "valueBase64";
+
+ // This was used in version 120 and before.
+ private static final String NULL_VALUE_OLD_STYLE = "null";
private final Object mLock;
@@ -364,12 +377,8 @@
for (int i = 0; i < settingCount; i++) {
Setting setting = settings.valueAt(i);
- serializer.startTag(null, TAG_SETTING);
- serializer.attribute(null, ATTR_ID, setting.getId());
- serializer.attribute(null, ATTR_NAME, setting.getName());
- serializer.attribute(null, ATTR_VALUE, packValue(setting.getValue()));
- serializer.attribute(null, ATTR_PACKAGE, packValue(setting.getPackageName()));
- serializer.endTag(null, TAG_SETTING);
+ writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(),
+ setting.getValue(), setting.getPackageName());
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[PERSISTED]" + setting.getName() + "=" + setting.getValue());
@@ -394,6 +403,64 @@
}
}
+ static void writeSingleSetting(int version, XmlSerializer serializer, String id,
+ String name, String value, String packageName) throws IOException {
+ if (id == null || isBinary(id) || name == null || isBinary(name)
+ || packageName == null || isBinary(packageName)) {
+ // This shouldn't happen.
+ return;
+ }
+ serializer.startTag(null, TAG_SETTING);
+ serializer.attribute(null, ATTR_ID, id);
+ serializer.attribute(null, ATTR_NAME, name);
+ setValueAttribute(version, serializer, value);
+ serializer.attribute(null, ATTR_PACKAGE, packageName);
+ serializer.endTag(null, TAG_SETTING);
+ }
+
+ static void setValueAttribute(int version, XmlSerializer serializer, String value)
+ throws IOException {
+ if (version >= SETTINGS_VERSOIN_NEW_ENCODING) {
+ if (value == null) {
+ // Null value -> No ATTR_VALUE nor ATTR_VALUE_BASE64.
+ } else if (isBinary(value)) {
+ serializer.attribute(null, ATTR_VALUE_BASE64, base64Encode(value));
+ } else {
+ serializer.attribute(null, ATTR_VALUE, value);
+ }
+ } else {
+ // Old encoding.
+ if (value == null) {
+ serializer.attribute(null, ATTR_VALUE, NULL_VALUE_OLD_STYLE);
+ } else {
+ serializer.attribute(null, ATTR_VALUE, value);
+ }
+ }
+ }
+
+ private String getValueAttribute(XmlPullParser parser) {
+ if (mVersion >= SETTINGS_VERSOIN_NEW_ENCODING) {
+ final String value = parser.getAttributeValue(null, ATTR_VALUE);
+ if (value != null) {
+ return value;
+ }
+ final String base64 = parser.getAttributeValue(null, ATTR_VALUE_BASE64);
+ if (base64 != null) {
+ return base64Decode(base64);
+ }
+ // null has neither ATTR_VALUE nor ATTR_VALUE_BASE64.
+ return null;
+ } else {
+ // Old encoding.
+ final String stored = parser.getAttributeValue(null, ATTR_VALUE);
+ if (NULL_VALUE_OLD_STYLE.equals(stored)) {
+ return null;
+ } else {
+ return stored;
+ }
+ }
+ }
+
private void readStateSyncLocked() {
FileInputStream in;
if (!mStatePersistFile.exists()) {
@@ -452,10 +519,9 @@
if (tagName.equals(TAG_SETTING)) {
String id = parser.getAttributeValue(null, ATTR_ID);
String name = parser.getAttributeValue(null, ATTR_NAME);
- String value = parser.getAttributeValue(null, ATTR_VALUE);
+ String value = getValueAttribute(parser);
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- mSettings.put(name, new Setting(name, unpackValue(value),
- unpackValue(packageName), id));
+ mSettings.put(name, new Setting(name, value, packageName, id));
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[RESTORED] " + name + "=" + value);
@@ -486,20 +552,6 @@
}
}
- private static String packValue(String value) {
- if (value == null) {
- return NULL_VALUE;
- }
- return value;
- }
-
- private static String unpackValue(String value) {
- if (NULL_VALUE.equals(value)) {
- return null;
- }
- return value;
- }
-
public final class Setting {
private String name;
private String value;
@@ -548,4 +600,58 @@
return true;
}
}
+
+ /**
+ * @return TRUE if a string is considered "binary" from KXML's point of view. NOTE DO NOT
+ * pass null.
+ */
+ public static boolean isBinary(String s) {
+ if (s == null) {
+ throw new NullPointerException();
+ }
+ // See KXmlSerializer.writeEscaped
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ boolean allowedInXml = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
+ if (!allowedInXml) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String base64Encode(String s) {
+ return Base64.encodeToString(toBytes(s), Base64.NO_WRAP);
+ }
+
+ private static String base64Decode(String s) {
+ return fromBytes(Base64.decode(s, Base64.DEFAULT));
+ }
+
+ // Note the followings are basically just UTF-16 encode/decode. But we want to preserve
+ // contents as-is, even if it contains broken surrogate pairs, we do it by ourselves,
+ // since I don't know how Charset would treat them.
+
+ private static byte[] toBytes(String s) {
+ final byte[] result = new byte[s.length() * 2];
+ int resultIndex = 0;
+ for (int i = 0; i < s.length(); ++i) {
+ char ch = s.charAt(i);
+ result[resultIndex++] = (byte) (ch >> 8);
+ result[resultIndex++] = (byte) ch;
+ }
+ return result;
+ }
+
+ private static String fromBytes(byte[] bytes) {
+ final StringBuffer sb = new StringBuffer(bytes.length / 2);
+
+ final int last = bytes.length - 1;
+
+ for (int i = 0; i < last; i += 2) {
+ final char ch = (char) ((bytes[i] & 0xff) << 8 | (bytes[i + 1] & 0xff));
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
}
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index 01c6ccf..ef863e7 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -2,7 +2,10 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+# Note we statically link SettingsState to do some unit tests. It's not accessible otherwise
+# because this test is not an instrumentation test. (because the target runs in the system process.)
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+ ../src/com/android/providers/settings/SettingsState.java
LOCAL_PACKAGE_NAME := SettingsProviderTest
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
index 8473db4..c7cc89b 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
@@ -39,8 +39,10 @@
protected static final String FAKE_SETTING_NAME = "fake_setting_name";
protected static final String FAKE_SETTING_NAME_1 = "fake_setting_name1";
+ protected static final String FAKE_SETTING_NAME_2 = "fake_setting_name2";
protected static final String FAKE_SETTING_VALUE = "fake_setting_value";
- protected static final String FAKE_SETTING_VALUE_1 = "fake_setting_value_1";
+ protected static final String FAKE_SETTING_VALUE_1 = SettingsStateTest.CRAZY_STRING;
+ protected static final String FAKE_SETTING_VALUE_2 = null;
private static final String[] NAME_VALUE_COLUMNS = new String[] {
Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index b89fb10..ad56b9d 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -230,10 +230,11 @@
// Make sure we have a clean slate.
deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1);
+ deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2);
try {
Uri uri = getBaseUriForType(type);
- ContentValues[] allValues = new ContentValues[2];
+ ContentValues[] allValues = new ContentValues[3];
// Insert the first setting.
ContentValues firstValues = new ContentValues();
@@ -241,15 +242,21 @@
firstValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE);
allValues[0] = firstValues;
- // Insert the first setting.
+ // Insert the second setting.
ContentValues secondValues = new ContentValues();
secondValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_1);
secondValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_1);
allValues[1] = secondValues;
+ // Insert the third setting. (null)
+ ContentValues thirdValues = new ContentValues();
+ thirdValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_2);
+ thirdValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_2);
+ allValues[2] = thirdValues;
+
// Verify insertion count.
final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues);
- assertSame("Couldn't insert both values", 2, insertCount);
+ assertSame("Couldn't insert both values", 3, insertCount);
// Make sure the first setting is there.
String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
@@ -258,10 +265,15 @@
// Make sure the second setting is there.
String secondValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_1);
assertEquals("Second setting must be present", FAKE_SETTING_VALUE_1, secondValue);
+
+ // Make sure the third setting is there.
+ String thirdValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_2);
+ assertEquals("Third setting must be present", FAKE_SETTING_VALUE_2, thirdValue);
} finally {
// Clean up.
deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1);
+ deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2);
}
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
new file mode 100644
index 0000000..3f9ffa1
--- /dev/null
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+package com.android.providers.settings;
+
+import android.test.AndroidTestCase;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+
+public class SettingsStateTest extends AndroidTestCase {
+ public static final String CRAZY_STRING =
+ "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000b\u000c\r" +
+ "\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a" +
+ "\u001b\u001c\u001d\u001e\u001f\u0020" +
+ "fake_setting_value_1" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "\u1000 \u2000 \u5000 \u8000 \uc000 \ue000" +
+ "\ud800\udc00\udbff\udfff" + // surrogate pairs
+ "\uD800ab\uDC00 " + // broken surrogate pairs
+ "日本語";
+
+
+ public void testIsBinary() {
+ assertFalse(SettingsState.isBinary(" abc 日本語"));
+
+ for (char ch = 0x20; ch < 0xd800; ch++) {
+ assertFalse("ch=" + Integer.toString(ch, 16),
+ SettingsState.isBinary(String.valueOf(ch)));
+ }
+ for (char ch = 0xe000; ch < 0xfffe; ch++) {
+ assertFalse("ch=" + Integer.toString(ch, 16),
+ SettingsState.isBinary(String.valueOf(ch)));
+ }
+
+ for (char ch = 0x0000; ch < 0x20; ch++) {
+ assertTrue("ch=" + Integer.toString(ch, 16),
+ SettingsState.isBinary(String.valueOf(ch)));
+ }
+ for (char ch = 0xd800; ch < 0xe000; ch++) {
+ assertTrue("ch=" + Integer.toString(ch, 16),
+ SettingsState.isBinary(String.valueOf(ch)));
+ }
+ assertTrue(SettingsState.isBinary("\ufffe"));
+ assertTrue(SettingsState.isBinary("\uffff"));
+ try {
+ assertFalse(SettingsState.isBinary(null));
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ /** Make sure we won't pass invalid characters to XML serializer. */
+ public void testWriteReadNoCrash() throws Exception {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ XmlSerializer serializer = Xml.newSerializer();
+ serializer.setOutput(os, StandardCharsets.UTF_8.name());
+ serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ serializer.startDocument(null, true);
+
+ for (int ch = 0; ch < 0x10000; ch++) {
+ checkWriteSingleSetting("char=0x" + Integer.toString(ch, 16), serializer,
+ "key", String.valueOf((char) ch));
+ }
+ checkWriteSingleSetting(serializer, "k", "");
+ checkWriteSingleSetting(serializer, "x", "abc");
+ checkWriteSingleSetting(serializer, "abc", CRAZY_STRING);
+ checkWriteSingleSetting(serializer, "def", null);
+
+ // Invlid input, but shouoldn't crash.
+ checkWriteSingleSetting(serializer, null, null);
+ checkWriteSingleSetting(serializer, CRAZY_STRING, null);
+ SettingsState.writeSingleSetting(
+ SettingsState.SETTINGS_VERSOIN_NEW_ENCODING,
+ serializer, null, "k", "v", "package");
+ SettingsState.writeSingleSetting(
+ SettingsState.SETTINGS_VERSOIN_NEW_ENCODING,
+ serializer, "1", "k", "v", null);
+ }
+
+ private void checkWriteSingleSetting(XmlSerializer serializer, String key, String value)
+ throws Exception {
+ checkWriteSingleSetting(key + "/" + value, serializer, key, value);
+ }
+
+ private void checkWriteSingleSetting(String msg, XmlSerializer serializer,
+ String key, String value) throws Exception {
+ // Make sure the XML serializer won't crash.
+ SettingsState.writeSingleSetting(
+ SettingsState.SETTINGS_VERSOIN_NEW_ENCODING,
+ serializer, "1", key, value, "package");
+ }
+
+ /**
+ * Make sure settings can be written to a file and also can be read.
+ */
+ public void testReadWrite() {
+ final File file = new File(getContext().getCacheDir(), "setting.xml");
+ file.delete();
+ final Object lock = new Object();
+
+ final SettingsState ssWriter = new SettingsState(lock, file, 1,
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ ssWriter.setVersionLocked(SettingsState.SETTINGS_VERSOIN_NEW_ENCODING);
+
+ ssWriter.insertSettingLocked("k1", "\u0000", "package");
+ ssWriter.insertSettingLocked("k2", "abc", "p2");
+ ssWriter.insertSettingLocked("k3", null, "p2");
+ ssWriter.insertSettingLocked("k4", CRAZY_STRING, "p3");
+ synchronized (lock) {
+ ssWriter.persistSyncLocked();
+ }
+
+ final SettingsState ssReader = new SettingsState(lock, file, 1,
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ synchronized (lock) {
+ assertEquals("\u0000", ssReader.getSettingLocked("k1").getValue());
+ assertEquals("abc", ssReader.getSettingLocked("k2").getValue());
+ assertEquals(null, ssReader.getSettingLocked("k3").getValue());
+ assertEquals(CRAZY_STRING, ssReader.getSettingLocked("k4").getValue());
+ }
+ }
+
+ /**
+ * In version 120, value "null" meant {code NULL}.
+ */
+ public void testUpgrade() throws Exception {
+ final File file = new File(getContext().getCacheDir(), "setting.xml");
+ file.delete();
+ final Object lock = new Object();
+ final PrintStream os = new PrintStream(new FileOutputStream(file));
+ os.print(
+ "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" +
+ "<settings version=\"120\">" +
+ " <setting id=\"0\" name=\"k0\" value=\"null\" package=\"null\" />" +
+ " <setting id=\"1\" name=\"k1\" value=\"\" package=\"\" />" +
+ " <setting id=\"2\" name=\"k2\" value=\"v2\" package=\"p2\" />" +
+ "</settings>");
+ os.close();
+
+ final SettingsState ss = new SettingsState(lock, file, 1,
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ synchronized (lock) {
+ SettingsState.Setting s;
+ s = ss.getSettingLocked("k0");
+ assertEquals(null, s.getValue());
+ assertEquals("null", s.getPackageName());
+
+ s = ss.getSettingLocked("k1");
+ assertEquals("", s.getValue());
+ assertEquals("", s.getPackageName());
+
+ s = ss.getSettingLocked("k2");
+ assertEquals("v2", s.getValue());
+ assertEquals("p2", s.getPackageName());
+ }
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index 0c84fa1..6278650 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -214,7 +214,7 @@
try (InputStream is = new FileInputStream(bugreportFile);
ZipOutputStream zos = new ZipOutputStream(
new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) {
- ZipEntry entry = new ZipEntry("bugreport.txt");
+ ZipEntry entry = new ZipEntry(bugreportFile.getName());
zos.putNextEntry(entry);
int totalBytes = Streams.copy(is, zos);
Log.v(TAG, "size of original bugreport: " + totalBytes + " bytes");
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 55d4c16..444f438 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Foon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Stembystand"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ontsluit"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ontsluit"</string>
<string name="phone_label" msgid="2320074140205331708">"maak foon oop"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"maak stembystand oop"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Jy sal nie deur klanke en vibrasies gesteur word nie, afgesien van wekkers, onthounotas, gebeurtenisse en bellers wat jy spesifiseer."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Pasmaak"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Dit blokkeer ALLE klanke en virbrasies, insluitend van wekkers, musiek, video\'s en speletjies af. Jy sal steeds foonoproepe kan maak."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Minder dringende kennisgewings hieronder"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Raak weer om oop te maak"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e8a12eb..9a68f1e 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ስልክ"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"የድምጽ እርዳታ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ክፈት"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ክፈት"</string>
<string name="phone_label" msgid="2320074140205331708">"ስልክ ክፈት"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"የድምጽ ረዳትን ክፈት"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"እርስዎ ከገለጿቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር በድምጾች እና ንዝረቶች አይረበሹም።"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"አብጅ"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ይሄ ከማንቂያዎች፣ ሙዚቃ፣ ቪዲዮዎች እና ጨዋታዎች የመጡትንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያግዳል። አሁንም የድምጽ ጥሪዎችን ማድረግ ይችላሉ።"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ለመክፈት ዳግም ይንኩ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 59b1bb3..e0fb2f0 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -91,6 +91,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"الهاتف"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"المساعد الصوتي"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"إلغاء القفل"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"إلغاء القفل"</string>
<string name="phone_label" msgid="2320074140205331708">"فتح الهاتف"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"فتح المساعد الصوتي"</string>
@@ -316,7 +320,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"لن يتم إزعاجك بأصوات أو اهتزاز، عدا من التنبيهات والتذكيرات والأحداث والمتصلين الذين تحددهم."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"تخصيص"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب. إلا أنه سيظل بإمكانك إجراء مكالمات هاتفية."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"الإشعارات الأقل إلحاحًا أدناه"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"المس مرة أخرى للفتح"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index d67192b..6f0eb1f 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Səs Yardımçısı"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Kiliddən çıxarın"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"kiliddən çıxarın"</string>
<string name="phone_label" msgid="2320074140205331708">"telefonu açın"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"səs yardımçısını açın"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Zəng, xatırlatma, hadisə və seçdiyiniz zəng edənlər istisna olmaqla səs və vibrasiya Sizi narahat etməyəcək."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Fərdiləşdirin"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Daha az təcili bildirişlər aşağıdadır"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 0f04afe..e542b20 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласова помощ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Отключване"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"отключване"</string>
<string name="phone_label" msgid="2320074140205331708">"отваряне на телефона"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отваряне на гласовата помощ"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Няма да бъдете обезпокоявани от звуци и вибрирания, различни от будилници, напомняния, събития и обаждания от посочени от вас контакти."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Персонализиране"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри. Пак ще можете да извършвате телефонни обаждания."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Ппоказване на по-малко спешните известия по-долу"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Докоснете отново за отваряне"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index a1fc870..bb3375b 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ফোন"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ভয়েস সহায়তা"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"আনলক করুন"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"আনলক করুন"</string>
<string name="phone_label" msgid="2320074140205331708">"ফোন খুলুন"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ভয়েস সহায়তা খুলুন"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাম দিকে স্লাইড করুন৷"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"আপনার নির্দিষ্ট অ্যালার্ম, অনুস্মারক, ইভেন্ট, এবং কলারগুলি ব্যতীত আপনাকে শব্দ এবং কম্পনগুলির দ্বারা বিরক্ত করা হবে না৷"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"কাস্টমাইজ করুন"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷ আপনি এখনও ফোন কলগুলি করতে পারবেন৷"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"খোলার জন্য আবার স্পর্শ করুন"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 7c25000..33efaeb 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telèfon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistència per veu"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloqueja"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloqueja"</string>
<string name="phone_label" msgid="2320074140205331708">"obre el telèfon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"obre l\'assistència per veu"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Llisca cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"No t\'interromprà cap so ni cap vibració, tret dels que produeixin les alarmes, els recordatoris, els esdeveniments i les trucades de les persones que especifiquis."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalitza"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos les alarmes, la música, els vídeos i els jocs. Tot i això, encara podràs fer trucades."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificacions menys urgents a continuació"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Torna a tocar per obrir"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index fc90efc..c7f19a3 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasová asistence"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odemknout"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"odemknout"</string>
<string name="phone_label" msgid="2320074140205331708">"otevřít telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"otevřít hlasovou asistenci"</string>
@@ -316,7 +320,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a volajících, které zadáte."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Přizpůsobit"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her. Telefonovat budete moci i nadále."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Méně urgentní oznámení níže"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Otevřete opětovným klepnutím"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0832ab7..88b8526 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås op"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"lås op"</string>
<string name="phone_label" msgid="2320074140205331708">"åbn telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"åbn voice assist"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Du bliver ikke forstyrret af lyde og vibrationer undtagen fra de alarmer, påmindelser, begivenheder og opkaldere, som du angiver."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpas"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Dette blokerer ALLE lyde og vibrationer, herunder fra alarmer, musik, videoer og spil. Du vil stadig kunne foretage telefonopkald."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Mindre presserende underretninger nedenfor"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tryk igen for at åbne"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 38fa55e..a87eec0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sprachassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Entsperren"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"Entsperren"</string>
<string name="phone_label" msgid="2320074140205331708">"Telefon öffnen"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"Sprachassistent öffnen"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von Ihnen festgelegten Personen."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe können Sie jedoch weiterhin tätigen."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Weniger dringende Benachrichtigungen unten"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Zum Öffnen erneut berühren"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c786902..cacf3b8 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Τηλέφωνο"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Φωνητική υποβοήθηση"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ξεκλείδωμα"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ξεκλείδωμα"</string>
<string name="phone_label" msgid="2320074140205331708">"άνοιγμα τηλεφώνου"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"άνοιγμα φωνητικής υποβοήθησης"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Δεν θα διακόπτεστε από ήχους και δονήσεις, με εξαίρεση τα ξυπνητήρια, τις υπενθυμίσεις, τα συμβάντα και τους καλούντες που έχετε ορίσει."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Προσαρμογή"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Αυτή η επιλογή αποκλείει ΟΛΟΥΣ τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Αγγίξτε ξανά για άνοιγμα"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 02b7b0a..07ac57af 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -87,6 +87,10 @@
<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>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<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>
@@ -312,7 +316,10 @@
<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="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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="8524949573675922138">"Touch again to open"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 02b7b0a..07ac57af 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -87,6 +87,10 @@
<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>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<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>
@@ -312,7 +316,10 @@
<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="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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="8524949573675922138">"Touch again to open"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 02b7b0a..07ac57af 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -87,6 +87,10 @@
<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>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<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>
@@ -312,7 +316,10 @@
<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="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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="8524949573675922138">"Touch again to open"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index f8d55fe..7ccb0ae 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"No te molestarán los sonidos ni las vibraciones, excepto que se trate de alarmas, recordatorios, eventos y emisores que especifiques."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluidas las que provienen de alarmas, videos y juegos. Podrás realizar llamadas telefónicas."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificaciones menos urgentes abajo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2ef2ab4..3563712 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"No te interrumpirán sonidos ni vibraciones, salvo los de las alarmas, los recordatorios, los eventos y las llamadas que especifiques."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Esta opción bloqueará TODOS los sonidos y todas las vibraciones, por ejemplo, los vídeos, los juegos, las alarmas y la música. Seguirás pudiendo hacer llamadas de teléfono."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificaciones menos urgente abajo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 4126325..6da6693 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Häälabi"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Luku avamine"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ava lukk"</string>
<string name="phone_label" msgid="2320074140205331708">"ava telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ava häälabi"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Teid segatakse helide ja värinaga vaid teie määratud alarmide, meeldetuletuste, sündmuste ning helistajate puhul."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Kohanda"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"See blokeerib KÕIK helid ja värinad, sh alarmide, muusika, videote ja mängude omad. Saate siiski helistada."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Vähem kiireloomulised märguanded on allpool"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Avamiseks puudutage uuesti"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 42a285b4..ef8f6e2 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonoa"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ahots-laguntza"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desblokeatu"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desblokeatu"</string>
<string name="phone_label" msgid="2320074140205331708">"ireki telefonoan"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ireki ahots-laguntza"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Lerratu ezkerrera hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Soinuek eta dardarek ez zaituzte eragotziko, zehazten dituzun alarmek, abisuek, gertaerek eta deitzaileek izan ezik."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Pertsonalizatu"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Soinu eta dardara GUZTIAK blokeatzen dira, besteak beste, alarmak, musika, bideoak eta jokoak. Telefono-deiak egiteko aukera izaten jarraituko duzu."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Irekitzeko, ukitu berriro"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 9b0195a..ce005e3 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"تلفن"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"دستیار صوتی"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"باز کردن قفل"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"بازکردن قفل"</string>
<string name="phone_label" msgid="2320074140205331708">"باز کردن تلفن"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"«دستیار صوتی» را باز کنید"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"صداها و لرزشهایی به جز هشدارها، یادآوریها، رویدادها و تماسگیرندههایی که مشخص میکنید، مزاحم شما نمیشوند."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"سفارشی کردن"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند. همچنان میتوانید تماس تلفنی برقرار کنید."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"اعلانهای کمتر فوری در زیر"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"برای باز کردن دوباره لمس کنید"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2d2cd02..633484c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Puhelin"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ääniapuri"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Avaa lukitus"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"avaa lukitus"</string>
<string name="phone_label" msgid="2320074140205331708">"avaa puhelin"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"Avaa ääniapuri"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Muokkaa"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät. Voit kuitenkin soittaa puheluita."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Avaa koskettamalla uudelleen"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index d9bbfe5..aa2f7d9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphone"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string>
<string name="phone_label" msgid="2320074140205331708">"Ouvrir le téléphone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous spécifiez."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez quand même faire des appels téléphoniques."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notifications moins urgentes affichées ci-dessous"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Touchez à nouveau pour ouvrir"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 9b916d8..0e0f1bb 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphoner"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string>
<string name="phone_label" msgid="2320074140205331708">"ouvrir le téléphone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous spécifiez."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez quand même passer des appels téléphoniques."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notifications moins urgentes ci-dessous"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Appuyer à nouveau pour ouvrir"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index c076a69..5c039cb 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir asistente de voz"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos de emisores de chamada especificados."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos. Aínda podes facer chamadas de teléfono."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificacións menos urxentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Toca outra vez para abrir o elemento"</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index fbd409e..c6193d8 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ફોન"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"વૉઇસ સહાય"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"અનલૉક કરો"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"અનલૉક કરો"</string>
<string name="phone_label" msgid="2320074140205331708">"ફોન ખોલો"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"વૉઇસ સહાય ખોલો"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ડાબે સ્લાઇડ કરો."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"તમને તમે ઉલ્લેખિત એલાર્મ્સ, સ્મૃતિપત્રો, ઇવેન્ટ્સ અને કૉલર્સ સિવાયના ધ્વનિઓ અને વાઇબ્રેશન્સથી ખલેલ પહોંચાડવામાં આવશે નહીં."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"કસ્ટમાઇઝ કરો"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત બધા ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે. તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"નીચે ઓછી તાકીદની સૂચનાઓ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ખોલવા માટે ફરી ટચ કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 7502d64..cd2e886 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"फ़ोन"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"वॉइस सहायक"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करें"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करें"</string>
<string name="phone_label" msgid="2320074140205331708">"फ़ोन खोलें"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"वॉइस सहायक खोलें"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्लाइड करें."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, ईवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"खोलने के लिए पुन: स्पर्श करें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 12d121e..52c01fa 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -88,6 +88,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Otključavanje"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"otključavanje"</string>
<string name="phone_label" msgid="2320074140205331708">"otvaranje telefona"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"otvaranje glasovne pomoći"</string>
@@ -313,7 +317,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Neće vas prekidati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre. I dalje ćete moći telefonirati."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Manje hitne obavijesti pri dnu"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Dodirnite ponovo da biste otvorili"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 4ddcfc4..b8db72a 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hangsegéd"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Feloldás"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"feloldás"</string>
<string name="phone_label" msgid="2320074140205331708">"telefon megnyitása"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"hangsegéd megnyitása"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nem zavarják majd hanghatások, sem rezgés, kivéve az ébresztéseket, emlékeztetőket, eseményeket és az Ön által megjelölt hívókat."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Személyre szabás"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is. Telefonhívást továbbra is fog tudni indítani."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"A kevésbé sürgős értesítések lentebb vannak"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Érintse meg ismét a megnyitáshoz"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 0ea11f9..ea39d8b 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Հեռախոս"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ձայնային հուշումներ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ապակողպել"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ապակողպել"</string>
<string name="phone_label" msgid="2320074140205331708">"բացել հեռախոսը"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"բացեք ձայնային հուշումը"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Ոչ մի ձայն և թրթռում չի անհանգստացնի ձեզ, բացառությամբ ձեր ընտրած զարթուցիչներից, հիշեցումներից, իրադարձություններից և զանգողներից:"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Հարմարեցնել"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռումները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայները: Սակայն կկարողանաք կատարել հեռախոսազանգեր:"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Պակաս հրատապ ծանուցումները ստորև"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Կրկին հպեք՝ բացելու համար"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 13decf9..1a771a3 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telepon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Bantuan Suara"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Buka kunci"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"buka kunci"</string>
<string name="phone_label" msgid="2320074140205331708">"buka ponsel"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"buka bantuan suara"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon tertentu."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Sesuaikan"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir. Anda tetap dapat melakukan panggilan telepon."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notifikasi kurang darurat di bawah"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Sentuh lagi untuk membuka"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index ea396ee..03ed3e8 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Sími"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Raddaðstoð"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Taka úr lás"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"taka úr lás"</string>
<string name="phone_label" msgid="2320074140205331708">"opna síma"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"opna raddaðstoð"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Strjúktu til vinstri til að <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Þú verður ekki fyrir truflunum af hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl sem þú leyfir fyrir fram."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Sérsníða"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum. Þú getur áfram hringt símtöl."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Minna áríðandi tilkynningar fyrir neðan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Snertu aftur til að opna"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 74b5705..d9fdd46 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Sblocca"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"sblocca"</string>
<string name="phone_label" msgid="2320074140205331708">"apri telefono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"apri Voice Assist"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Non verrai disturbato da suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi e chiamate da contatti da te specificati."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizza"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi. Potrai ancora telefonare."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notifiche meno urgenti in basso"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tocca di nuovo per aprire"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 2eea259..92188d3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"טלפון"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"מסייע קולי"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ביטול נעילה"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"בטל את הנעילה"</string>
<string name="phone_label" msgid="2320074140205331708">"פתח את הטלפון"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"פתח את המסייע הקולי"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"צלילים ורטט לא יופעלו, פרט להתראות, תזכורות, אירועים ומתקשרים שתציין."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"התאם אישית"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"פעולה זו חוסמת את כל הצלילים והרטט, כולל התראות, מוזיקה, סרטונים ומשחקים. תוכל עדיין להתקשר."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"הודעות בדחיפות נמוכה יותר בהמשך"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"גע שוב כדי לפתוח"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 124db15..5ea8ef9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"音声アシスト"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ロック解除"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ロック解除"</string>
<string name="phone_label" msgid="2320074140205331708">"電話を起動"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"音声アシストを開く"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"アラーム、リマインダー、予定、指定した人からの着信以外で音やバイブレーションに煩わされることはありません。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"カスタマイズ"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。電話をかけることはできます。"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"緊急度の低い通知を下に表示"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"開くにはもう一度タップしてください"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index f9aa911..0dbc85e 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ტელეფონი"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ხმოვანი დახმარება"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"განბლოკვა"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"განბლოკვა"</string>
<string name="phone_label" msgid="2320074140205331708">"ტელეფონის გახსნა"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ხმოვანი დახმარების გახსნა"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"თქვენ მიერ მითითებული გაფრთხილებების, შეხსენებების, ღონისძიებებისა და აბონენტების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"მორგება"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ეს ბლოკავს ყველა ხმაურს და ვიბრაციას, მათ შორის, გაფრთხილებებით, მუსიკით, ვიდეოებით და თამაშებით შექმნილს. მიუხედავად ამისა, თქვენ შეძლებთ სატელეფონო ზარების განხორციელებას."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"შეეხეთ ისევ გასახსნელად"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 8e35f68..6d22c3d 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дауыс көмекшісі"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Бекітпесін ашу"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"бекітпесін ашу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонды ашу"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ашық дауыс көмекшісі"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үшін солға сырғыту."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Дабылдар, еске салғыштар, оқиғалар мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Реттеу"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Дабыл, музыка, бейнелер мен ойындарды қоса алғанда, барлық дыбыстар мен дірілдер тыйылатын болады. Қоңырау шала беруіңізге болады."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Шұғылдығы азырақ хабарландырулар төменде"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ашу үшін қайтадан түртіңіз"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 62ea93c..0a6b62c 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ទូរស័ព្ទ"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ជំនួយសំឡេង"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ដោះសោ"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ដោះសោ"</string>
<string name="phone_label" msgid="2320074140205331708">"បើកទូរស័ព្ទ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"បើកជំនួយសំឡេង"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"អ្នកនឹងមិនរំខានដោយសម្លេង និងរំញ័រឡើយ លើកលែងតែសម្លេងរោទិ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅដែលអ្នកបានបញ្ជាក់ប៉ុណ្ណោះ។"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ប្ដូរតាមបំណង"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ ដោយរួមបញ្ចូលទាំងសំឡេងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។ អ្នកនឹងនៅតែអាចធ្វើការហៅទូរស័ព្ទបានដដែល។"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ប៉ះម្ដងទៀតដើម្បីបើក"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 61348bc..5a90439 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ಫೋನ್"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ಅನ್ಲಾಕ್"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ಅನ್ಲಾಕ್ ಮಾಡು"</string>
<string name="phone_label" msgid="2320074140205331708">"ಫೋನ್ ತೆರೆಯಿರಿ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"ಅಲಾರಮ್ಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್ಗಳು ಮತ್ತು ನೀವು ಸೂಚಿಸುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ, ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳಿಂದ ನಿಮಗೆ ತೊಂದರೆ ಆಗುವುದಿಲ್ಲ."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ಕಸ್ಟಮೈಸ್ ಮಾಡು"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ಇದು ಅಲಾರಮ್ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಗೇಮ್ಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ತೆರೆಯಲು ಮತ್ತೊಮ್ಮೆ ಸ್ಪರ್ಶಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f154261..2895fdf 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"전화"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"음성 지원"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"잠금 해제"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"잠금 해제"</string>
<string name="phone_label" msgid="2320074140205331708">"휴대전화 열기"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"음성 지원 열기"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"지정한 알람, 알림, 이벤트, 발신자를 제외하고 소리와 진동을 끕니다."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"맞춤설정"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다. 전화는 걸 수 있습니다."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"아래에 덜 급한 알림 표시"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"다시 터치하여 열기"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 16ca9a0..c48b6bb 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -111,6 +111,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Үн жардамчысы"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Кулпусун ачуу"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"кулпуну ачуу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонду ачуу"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"үн жардамчысысын ачуу"</string>
@@ -337,7 +341,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үчүн солго жылмыштырыңыз."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Көрсөтүлгөн эскертүүлөрдөн, эскерткичтерден, окуялардан жана чалуучулардан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Ыңгайлаштыруу"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү сыяктуу нерселердин баары өчүрүлөт. Бирок телефон чала бересиз."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Анчейин шашылыш эмес эскертмелер төмөндө"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ачуу үчүн кайра тийиңиз"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index c3be29a..1316a4a 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ໂທລະສັບ"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ຊ່ວຍເຫຼືອທາງສຽງ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ປົດລັອກ"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ປົດລັອກ"</string>
<string name="phone_label" msgid="2320074140205331708">"ເປີດແປ້ນໂທລະສັບ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ຊ່ວເຫຼືອເປີດສຽງ"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"ທ່ານຈະບໍ່ຖືກລົບກວນຈາກສຽງ ແລະການສັ່ນ, ຍົກເວັ້ນຈາກໂມງປຸກ, ການເຕືອນ, ເຫດການ, ແລະຜູ້ໂທທີ່ທ່ານລະບຸ."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ປັບແຕ່ງ"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ອັນນີ້ບລັອກທຸກສຽງ ແລະການສັ່ນ, ລວມທັງຈາກໂມງປຸກ, ເພງ, ວິດີໂອ, ແລະເກມ. ທ່ານຍັງຈະສາມາດໂທລະສັບໄດ້."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ແຕະອີກເທື່ອນຶ່ງເພື່ອເປີດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ba52291..bbe008f 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonas"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atrakinti"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"atrakinti"</string>
<string name="phone_label" msgid="2320074140205331708">"atidaryti telefoną"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"atidaryti „Voice Assist“"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus ir vibravimą."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Tinkinti"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą. Vis tiek galėsite skambinti telefonu."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Mažiau skubūs pranešimai toliau"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Palieskite dar kartą, kad atidarytumėte"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index dd1ec14..2350e35 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -88,6 +88,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Tālruņa numurs"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Balss palīgs"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atbloķēt"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"atbloķēt"</string>
<string name="phone_label" msgid="2320074140205331708">"atvērt tālruni"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"atvērt balss palīgu"</string>
@@ -313,7 +317,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Jūs netraucēs skaņas un vibrosignāli, ja vien tie nebūs modinātāji, atgādinājumi, pasākumi vai konkrēti zvanītāji, kurus būsiet norādījis."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Pielāgot"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli. Jūs joprojām varēsiet veikt tālruņa zvanus."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Pieskarieties vēlreiz, lai atvērtu."</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 9ab5f36..30da026 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помош"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Отклучување"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"отклучи"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовна помош"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Лизгај налево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Нема да ви пречат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Приспособи"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите. Сѐ уште ќе може да воспоставувате телефонски повици."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Долу се помалку итни известувања"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Допрете повторно за да отворите"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index ba77986..7c8fdc1 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ഫോണ്"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"വോയ്സ് സഹായം"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"അണ്ലോക്ക് ചെയ്യുക"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"അൺലോക്കുചെയ്യുക"</string>
<string name="phone_label" msgid="2320074140205331708">"ഫോൺ തുറക്കുക"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"വോയ്സ് അസിസ്റ്റ് തുറക്കുക"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി ഇടത്തേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"നിങ്ങൾ വ്യക്തമാക്കിയിട്ടുള്ള അലാറങ്ങൾ, ഓർമ്മപ്പെടുത്തലുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവ ഒഴികെയുള്ള ശബ്ദങ്ങളോ വൈബ്രേഷനുകളോ കാരണം നിങ്ങൾക്ക് ശല്യമുണ്ടാകില്ല."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ഇഷ്ടാനുസൃതമാക്കുക"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു. നിങ്ങൾക്ക് തുടർന്നും ഫോൺ വിളിക്കാനാകും."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"തുറക്കുന്നതിന് വീണ്ടും സ്പർശിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index f5fe7b8..bcfe687 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -85,6 +85,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Утас"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дуут туслах"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Тайлах"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"тайлах"</string>
<string name="phone_label" msgid="2320074140205331708">"утас нээх"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"дуут туслахыг нээнэ"</string>
@@ -310,7 +314,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Танд сэрүүлгэ, сануулга, үйл явдлын сануулга, таны сануулсан дуудлага зэргээс бусад дуу чимээ, чичиргээ танд садаа болохгүй."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Тохируулах"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Энэ нь сануулга, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог. Та дуудлага хийх боломжтой хэвээр л байна."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Яаралтай биш мэдэгдлүүдийг доор"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Нээхийн тулд дахин хүрнэ үү"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 253e607..ee509f4 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"व्हॉइस सहाय्य"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करा"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करा"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन उघडा"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"व्हॉइस सहाय्य उघडा"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"आपण निर्दिष्ट करता ते अलार्म, स्मरणपत्रे, इव्हेंट आणि कॉलर व्यतिरिक्त, आपल्याला आवाज आणि कंपनांमुळे व्यत्यय येणार नाही."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"सानुकूलित करा"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते. आपण तरीही फोन कॉल करण्यात सक्षम व्हाल."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"खाली कमी तातडीच्या सूचना"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"उघडण्यासाठी पुन्हा स्पर्श करा"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index bdde8ee..aef1def 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Bantuan Suara"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Buka kunci"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"buka kunci"</string>
<string name="phone_label" msgid="2320074140205331708">"buka telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"buka bantuan suara"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh bunyi dan getaran kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tentukan."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Peribadikan"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Mesej ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan. Anda masih boleh membuat panggilan telefon."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Pemberitahuan kurang penting di bawah"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Sentuh sekali lagi untuk membuka"</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 0149130..332592b 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ဖုန်း"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"အသံ အကူအညီ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"သော့ဖွင့်ရန်"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string>
<string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် ဖယ်ဘက်ကို ပွတ်ဆွဲပါ"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"နှိုးစက်များ၊ အသိပေးချက်များ၊ ဖြစ်ရပ်များ နှင့် သင်သတ်မှတ်ထားသည့် ခေါ်ဆိုသူများမှ လွဲ၍ အသံများနှင့် တုန်ခါမှုများသည် သင့်အား နှောင့်ယှက်မည် မဟုတ်ပါ။"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"စိတ်ကြိုက် ပြုလုပ်ရန်"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ဤအရာမှ နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား တားဆီးပေးသည်။ ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်နိုင်ဆဲဖြစ်မည်။"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ဖွင့်ရန် ထပ်ပြီး ထိပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3f1d184..a7d3474 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Talehjelp"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås opp"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"lås opp"</string>
<string name="phone_label" msgid="2320074140205331708">"åpne telefonen"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"åpne talehjelp"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir ikke forstyrret av lyder og vibrasjoner, bortsett fra alarmer, påminnelser, aktiviteter og oppringere du angir."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpass"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill. Du kan fremdeles ringe."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Mindre presserende varsler nedenfor"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Trykk på nytt for å åpne"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 5100f43..7cf0ed0 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"आवाज सहायता"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"खोल्नुहोस्"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"खोल्नुहोस्"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन खोल्नुहोस्"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"आवाज सहायता खोल्नुहोस्"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"अलार्म, रिमाइन्डर, घटना, र तपाईँले निर्दिष्ट गर्नुहुने कलरहरू देखि बाहेक, आवाज र कम्पनले तपाईँ लाई वाधा गर्ने छैन।"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"अनुकूलन गर्नुहोस्"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन निषेध गर्छ। तपाईँ अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"तल कम जरुरी सूचनाहरू"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"खोल्न फेरि छुनुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7585fb8..ded227a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Spraakassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ontgrendelen"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ontgrendelen"</string>
<string name="phone_label" msgid="2320074140205331708">"telefoon openen"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"spraakassistent openen"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"U wordt niet gestoord door geluiden en trillingen, behalve voor alarmen, herinneringen, afspraken en bellers die u specificeert."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Aanpassen"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games. U kunt wel nog steeds bellen."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Minder urgente meldingen onderaan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Raak opnieuw aan om te openen"</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 91fb6d4..45f852c 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ਫੋਨ"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ਵੌਇਸ ਅਸਿਸਟ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ਅਨਲੌਕ ਕਰੋ"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ਅਨਲੌਕ ਕਰੋ"</string>
<string name="phone_label" msgid="2320074140205331708">"ਫੋਨ ਖੋਲ੍ਹੋ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ਵੌਇਸ ਅਸਿਸਟ ਖੋਲ੍ਹੋ"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਨਿਰਦਿਸ਼ਟ ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਇਵੈਂਟਸ, ਅਤੇ ਕਾਲਰਸ ਤੋਂ ਇਲਾਵਾ, ਧੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਤੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ਅਨੁਕੂਲਿਤ ਕਰੋ"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀ ਦੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ।"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਛੋਹਵੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d8bec72..75ea440 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asystent głosowy"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odblokuj"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"odblokuj"</string>
<string name="phone_label" msgid="2320074140205331708">"otwórz telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"otwórz pomoc głosową"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Urządzenie nie będzie odtwarzać dźwięków ani włączać wibracji, z wyjątkiem wybranych przez Ciebie alarmów, przypomnień, wydarzeń i kontaktów."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Dostosuj"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Zablokuje WSZYSTKIE dźwięki i wibracje, także alarmy, muzykę, filmy i gry. Nadal będzie można wykonywać połączenia."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Poniżej widać mniej pilne powiadomienia"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Kliknij ponownie, by otworzyć"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index a1351dd..1741c1c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telemóvel"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistente de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir telemóvel"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir assistente de voz"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, músicas, vídeos e jogos. Continua a poder telefonar."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tocar novamente para abrir"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 5f2603e..4ba9ec1 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefone"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistência de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir telefone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"abrir assistência de voz"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Você não será perturbado por sons e vibrações, com exceção de alarmes, lembretes, eventos e autores de chamadas que você especificar."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos. Você ainda poderá fazer chamadas telefônicas."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Toque novamente para abrir"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9b5a785..24e2a58 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -88,6 +88,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistent vocal"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Deblocați"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"deblocați"</string>
<string name="phone_label" msgid="2320074140205331708">"deschideți telefonul"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"deschideți asistentul vocal"</string>
@@ -313,7 +317,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nu veți fi deranjat(ă) de sunete și vibrații, exceptând alarmele, mementourile, evenimentele și apelanții pe care îi menționați."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizați"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor. Totuși, veți putea iniția apeluri."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Notificările mai puțin urgente mai jos"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Atingeți din nou pentru a deschide"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index fd239ca..f16d59e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон."</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Аудиоподсказки"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Разблокировать."</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"Разблокировать."</string>
<string name="phone_label" msgid="2320074140205331708">"Открыть телефон."</string>
<string name="voice_assist_label" msgid="3956854378310019854">"включить аудиоподсказки"</string>
@@ -316,7 +320,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Вибрация и звуки будут отключены. Вы услышите только сигналы будильника, напоминания, уведомления о мероприятиях и звонки от выбранных абонентов."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Настроить"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Этот режим заблокирует все звуки и вибрацию, в том числе для будильника, музыки, видео и игр. Вы сможете разговаривать по телефону."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Показать менее важные оповещения"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Нажмите ещё раз, чтобы открыть"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index a7ac3cf..3d7dc47 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"දුරකථනය"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"හඬ සහාය"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"අඟුල අරින්න"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"අඟුල අරින්න"</string>
<string name="phone_label" msgid="2320074140205331708">"දුරකථනය විවෘත කරන්න"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"විවෘත හඬ සහාය"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා වමට සර්පණය කරන්න."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"එලාම, සිහි කැඳවීම්, සිදුවීම් සහ ඔබ සඳහන් කරන අමතන්නන් වෙතින් හැර, වෙනත් ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"අභිරුචිකරණය"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"මෙය එලාම, සංගීතය, වීඩියෝ, සහ ක්රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි. ඔබට තවමත් දුරකථන ඇමතුම් සිදු කිරීමේ හැකියාව ඇත."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"හදිසිය අඩු දැනුම් දීම් පහත"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"විවෘත කිරීමට නැවත ස්පර්ශ කරන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 57fa578..ce92e4a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefón"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasový asistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odomknúť"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"odomknúť"</string>
<string name="phone_label" msgid="2320074140205331708">"otvoriť telefón"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"otvoriť hlasového asistenta"</string>
@@ -316,7 +320,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudú vás rušiť zvuky ani vibrácie s výnimkou budíkov, pripomenutí, udalostí a volajúcich, ktoré špecifikujete."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Prispôsobiť"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier. Naďalej budete môcť telefonovať."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Otvorte opätovným klepnutím"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index f2b4801..3ca6edb3 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovni pomočnik"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odkleni"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"odkleni"</string>
<string name="phone_label" msgid="2320074140205331708">"odpri telefon"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"odpri glasovnega pomočnika"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Ne bodo vas motili zvoki in vibriranje, razen od alarmov, opomnikov, dogodkov in klicateljev, ki jih določite."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger. Še vedno boste lahko opravljali telefonske klice."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Manj nujna obvestila spodaj"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Dotaknite se znova, če želite odpreti"</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 1747964..3882802 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoni"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ndihma zanore"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Shkyç"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"shkyç"</string>
<string name="phone_label" msgid="2320074140205331708">"hap telefonin"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"hap ndihmën zanore"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Rrëshqit majtas për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç atyre nga alarmet, rikujtesat, ngjarjet dhe telefonuesit që specifikon."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizo"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat. Përsëri do të mund të bësh telefonata."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Njoftimet më pak urgjente, më poshtë!"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Prek sërish për ta hapur"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d63e0df..dd79218 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -88,6 +88,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помоћ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Откључајте"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"откључај"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовну помоћ"</string>
@@ -313,7 +317,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Неће вас узнемиравати звукови и вибрације, осим за аларме, подсетнике, догађаје и позиваоце које изаберете."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Прилагоди"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Мање хитна обавештења су у наставку"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Додирните поново да бисте отворили"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index c2c4727..23a61ca 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Mobil"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Röstassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås upp"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"lås upp"</string>
<string name="phone_label" msgid="2320074140205331708">"öppna mobilen"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"öppna röstassistenten"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, event och specifika samtal."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassa"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel. Du kan fortfarande ringa."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Mindre brådskande aviseringar nedan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tryck igen för att öppna"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index f9148b9..975f269 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Simu"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Mapendekezo ya Sauti"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Fungua"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"fungua"</string>
<string name="phone_label" msgid="2320074140205331708">"fungua simu"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"fungua mapendekezo ya sauti"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na wapigaji simu utakaobainisha."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Badilisha kukufaa"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa na pamoja na inayotoka kwenye kengele, muziki, video na michezo. Bado utaweza kupiga simu."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Arifa zisizo za dharura sana ziko hapo chini"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Gusa tena ili ufungue"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 31c3fcc..e79eb4a 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ஃபோன்"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"குரல் உதவி"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"திற"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"திற"</string>
<string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு இடதுபக்கமாக இழுக்கவும்."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள், குறிப்பிட்ட அழைப்புகள் தவிர, ஒலிகளினாலும் அதிர்வினாலும் தொந்தரவு இருக்காது."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"தனிப்பயனாக்கு"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா சத்தங்களையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"திறக்க, மீண்டும் தட்டவும்"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 6701082..7aaa6e2 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ఫోన్"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"వాయిస్ సహాయకం"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"అన్లాక్ చేయి"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"అన్లాక్ చేయి"</string>
<string name="phone_label" msgid="2320074140205331708">"ఫోన్ను తెరువు"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ సహాయకం తెరువు"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం ఎడమవైపుకు స్లైడ్ చేయండి."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"మీరు అలారాలు, రిమైండర్లు, ఈవెంట్లు మరియు పేర్కొనే కాలర్ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్లతో మీకు అంతరాయం కలగదు."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"అనుకూలీకరించు"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్లను బ్లాక్ చేస్తుంది. మీరు ఇప్పటికీ ఫోన్ కాల్లు చేయగలుగుతారు."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"తక్కువ అత్యవసర నోటిఫికేషన్లు దిగువన"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"తెరవడానికి మళ్లీ తాకండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ad5e551..52afa6a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"โทรศัพท์"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"ตัวช่วยเสียง"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ปลดล็อก"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"ปลดล็อก"</string>
<string name="phone_label" msgid="2320074140205331708">"เปิดโทรศัพท์"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"เปิดตัวช่วยเสียง"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นการปลุก การเตือนความจำ กิจกรรม และผู้โทรที่คุณระบุ"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"กำหนดค่า"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"การตั้งค่านี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม คุณจะยังสามารถโทรออกได้อยู่"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"แตะอีกครั้งเพื่อเปิด"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index fbedb5d..db89571 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telepono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"I-unlock"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"i-unlock"</string>
<string name="phone_label" msgid="2320074140205331708">"buksan ang telepono"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"buksan ang voice assist"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Hindi ka magagambala ng mga tunog at pag-vibrate, maliban mula sa mga alarm, paalala, kaganapan at mga tinukoy mong tumatawag."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"I-customize"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro. Magagawa mo pa ring makatawag."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Pinduting muli upang buksan"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b638556..177c1bc 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sesli Yardım"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Kilidi aç"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"kilidi aç"</string>
<string name="phone_label" msgid="2320074140205331708">"telefonu aç"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"sesli yardımı aç"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Belirttiğiniz alarmlar, hatırlatıcılar, etkinlikler ve arayanlar hariç olmak üzere, sesler ve titreşimlerle rahatsız edilmeyeceksiniz."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Özelleştir"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir. Telefon aramaları yapmaya devam edebileceksiniz."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Daha az acil bildirimler aşağıdadır"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Açmak için tekrar dokunun"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2946ad1..2209374 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -89,6 +89,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Номер телефону"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Голосові підказки"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Розблокувати"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"розблокувати"</string>
<string name="phone_label" msgid="2320074140205331708">"відкрити телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"запустити голосові підказки"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Ви отримуватимете звукові й вібросигнали лише для вибраних сповіщень, нагадувань, повідомлень про події та викликів абонентів."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Налаштувати"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема сповіщення, музика, відео й ігри. Ви зможете телефонувати."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Менше термінових сповіщень нижче"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Торкніться знову, щоб відкрити"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 2bb7dff..0c1c32c 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"فون"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"صوتی معاون"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"غیر مقفل کریں"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"غیر مقفل کریں"</string>
<string name="phone_label" msgid="2320074140205331708">"فون کھولیں"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"صوتی معاون کھولیں"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے بائیں سلائیڈ کریں۔"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"الارمز، یاد دہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"حسب ضرورت بنائیں"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔ آپ ابھی بھی فون کالز کر سکیں گے۔"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"کم اہم اطلاعات ذیل میں ہیں"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"کھولنے کیلئے دوبارہ ٹچ کریں"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 55ca4b5..b65485d 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ovozli yordam"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Qulfdan chiqarish"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"qulfdan chiqarish"</string>
<string name="phone_label" msgid="2320074140205331708">"telefonni ochish"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ovozli yordamni yoqish"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun chapga suring."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq uyg‘otkich signallari, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan qo‘ng‘iroqlar bundan mustasno."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Sozlash"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Ushbu rejimda BARCHA ovoz va tebranishlar, jumladan, uyg‘otkich signallari, musiqa va o‘yinlar ovozlari ham o‘chirib qo‘yiladi. Shunday bo‘lsa-da, qo‘ng‘iroqlarni bemalol amalga oshirishingiz mumkin."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Kam ahamiyatli bildirishnomalarni pastda ko‘rsatish"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ochish uchun yana bosing"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7a6bef5..2e1b978 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Điện thoại"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Trợ lý thoại"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Mở khóa"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"mở khóa"</string>
<string name="phone_label" msgid="2320074140205331708">"mở điện thoại"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"mở trợ lý thoại"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, nhắc nhở, sự kiện và người gọi mà bạn chỉ định."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Tùy chỉnh"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Chế độ này sẽ chặn TẤT CẢ âm thanh và tiếng rung, bao gồm báo thức, âm nhạc, video và trò chơi. Bạn vẫn có thể gọi điện thoại."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Thông báo ít khẩn cấp hơn bên dưới"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Chạm lại để mở"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b34d547..d77147f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"电话"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"语音助理"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解锁"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"解锁"</string>
<string name="phone_label" msgid="2320074140205331708">"打开电话"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"打开语音助理"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"您将不会受声音和振动的打扰,但闹钟、提醒、活动和您指定的来电者除外。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"自定义"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。您仍然可以拨打电话。"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"不太紧急的通知会显示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次触摸即可打开"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 02187b3..9ce90e3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"語音助手"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解鎖"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"解鎖"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"開啟語音助手"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"除了指定的鬧鐘、提醒、活動及來電者,您將不會受到其他聲音和震動騷擾。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片及遊戲,但您仍可撥打電話。"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"不太緊急的通知會在下方顯示"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e58b043..367b4a3 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"語音小幫手"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解除鎖定"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"解除鎖定"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"開啟語音小幫手"</string>
@@ -314,7 +318,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"您不會受到聲音和震動干擾,但鬧鐘、提醒、活動和指定來電者除外。"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。您仍可以撥打電話。"</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 23010b1..7ad977f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -87,6 +87,10 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Ifoni"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Isisekeli sezwi"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Vula"</string>
+ <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
+ <skip />
+ <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+ <skip />
<string name="unlock_label" msgid="8779712358041029439">"vula"</string>
<string name="phone_label" msgid="2320074140205331708">"vula ifoni"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"vula isilekeleli sezwi"</string>
@@ -312,7 +316,10 @@
<string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Ngeke uze uphazanyiswe yimisindo nokudlidliza, ngaphandle kokuvela kuma-alamu, izikhumbuzi, imicimbi, nabashayi obacacisayo."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Enza ngendlela oyifisayo"</string>
- <string name="zen_silence_introduction" msgid="575422795504098868">"Lokhu kuvimbela YONKE imisindo nokudludliza, kufaka phakathi ama-alamu, umculo, amavidiyo, namageyimu. Usazokwazi ukwenza amkholi wefoni."</string>
+ <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
+ <skip />
+ <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+ <skip />
<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">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Thinta futhi ukuze uvule"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 674356b..7838119 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -311,4 +311,12 @@
public void showDisclosure() {
mAssistDisclosure.postShow();
}
+
+ public void onUserSwitched(int newUserId) {
+ updateAssistInfo();
+ }
+
+ public void prepareBeforeInvocation() {
+ updateAssistInfo();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index d6a16fa..77c27fa 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -30,6 +30,8 @@
import android.provider.Settings;
import android.widget.ImageView;
+import com.android.internal.logging.MetricsLogger;
+
import java.util.ArrayList;
public class BrightnessController implements ToggleSlider.Listener {
@@ -195,12 +197,16 @@
}
@Override
- public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
+ public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
+ boolean stopTracking) {
updateIcon(mAutomatic);
if (mExternalChange) return;
if (!mAutomatic) {
final int val = value + mMinimumBacklight;
+ if (stopTracking) {
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS, val);
+ }
setBrightness(val);
if (!tracking) {
AsyncTask.execute(new Runnable() {
@@ -213,6 +219,9 @@
}
} else {
final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
+ if (stopTracking) {
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS_AUTO, value);
+ }
setBrightnessAdj(adj);
if (!tracking) {
AsyncTask.execute(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 74267a5..cef4d34 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -24,6 +24,7 @@
import android.view.WindowManager;
import android.widget.ImageView;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
/** A dialog that provides controls for adjusting the screen brightness. */
@@ -52,11 +53,13 @@
protected void onStart() {
super.onStart();
mBrightnessController.registerCallbacks();
+ MetricsLogger.visible(this, MetricsLogger.BRIGHTNESS_DIALOG);
}
@Override
protected void onStop() {
super.onStop();
+ MetricsLogger.hidden(this, MetricsLogger.BRIGHTNESS_DIALOG);
mBrightnessController.unregisterCallbacks();
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
index cdb8e69..d247711 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
@@ -35,7 +35,8 @@
public class ToggleSlider extends RelativeLayout {
public interface Listener {
public void onInit(ToggleSlider v);
- public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value);
+ public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value,
+ boolean stopTracking);
}
private Listener mListener;
@@ -143,7 +144,7 @@
if (mListener != null) {
mListener.onChanged(
- ToggleSlider.this, mTracking, checked, mSlider.getProgress());
+ ToggleSlider.this, mTracking, checked, mSlider.getProgress(), false);
}
if (mMirror != null) {
@@ -157,7 +158,7 @@
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mListener != null) {
mListener.onChanged(
- ToggleSlider.this, mTracking, mToggle.isChecked(), progress);
+ ToggleSlider.this, mTracking, mToggle.isChecked(), progress, false);
}
}
@@ -166,8 +167,8 @@
mTracking = true;
if (mListener != null) {
- mListener.onChanged(
- ToggleSlider.this, mTracking, mToggle.isChecked(), mSlider.getProgress());
+ mListener.onChanged(ToggleSlider.this, mTracking, mToggle.isChecked(),
+ mSlider.getProgress(), false);
}
mToggle.setChecked(false);
@@ -183,8 +184,8 @@
mTracking = false;
if (mListener != null) {
- mListener.onChanged(
- ToggleSlider.this, mTracking, mToggle.isChecked(), mSlider.getProgress());
+ mListener.onChanged(ToggleSlider.this, mTracking, mToggle.isChecked(),
+ mSlider.getProgress(), true);
}
if (mMirrorController != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 295fdc8..9d6204c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1613,17 +1613,11 @@
/**
* The LEDs are turned off when the notification panel is shown, even just a little bit.
- * This was added last-minute and is inconsistent with the way the rest of the notifications
- * are handled, because the notification isn't really cancelled. The lights are just
- * turned off. If any other notifications happen, the lights will turn back on. Steve says
- * this is what he wants. (see bug 1131461)
*/
protected void handleVisibleToUserChanged(boolean visibleToUser) {
try {
if (visibleToUser) {
- // Only stop blinking, vibrating, ringing when the user went into the shade
- // manually (SHADE or SHADE_LOCKED).
- boolean clearNotificationEffects =
+ boolean clearNotificationEffects = mShowLockscreenNotifications ||
(mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
mBarService.onPanelRevealed(clearNotificationEffects);
} else {
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 094d5f0..39a06aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -172,12 +172,7 @@
public void onAnimationEnd(Animator animation) {
mPeekAnimator = null;
if (mCollapseAfterPeek && !mCancelled) {
- postOnAnimation(new Runnable() {
- @Override
- public void run() {
- collapse(false /* delayed */, 1.0f /* speedUpFactor */);
- }
- });
+ postOnAnimation(mPostCollapseRunnable);
}
mCollapseAfterPeek = false;
}
@@ -663,6 +658,11 @@
(animator.getDuration() * getCannedFlingDurationFactor()
/ collapseSpeedUpFactor));
}
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD
+ && mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+ Log.i(PhoneStatusBar.TAG, "Panel collapsed! Stacktrace: "
+ + Log.getStackTraceString(new Throwable()));
+ }
}
animator.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ade40e5..9e6dd7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -96,6 +96,7 @@
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.ViewMediatorCallback;
@@ -457,7 +458,8 @@
private int mDisabledUnmodified2;
/** Keys of notifications currently visible to the user. */
- private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
+ private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
+ new ArraySet<>();
private long mLastVisibilityReportUptimeMs;
private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
@@ -471,9 +473,7 @@
private int mLastLoggedStateFingerprint;
private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
- | StackViewState.LOCATION_TOP_STACK_PEEKING
- | StackViewState.LOCATION_MAIN_AREA
- | StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
+ | StackViewState.LOCATION_MAIN_AREA;
private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
new OnChildLocationsChangedListener() {
@@ -498,12 +498,17 @@
// Tracks notifications currently visible in mNotificationStackScroller and
// emits visibility events via NoMan on changes.
private final Runnable mVisibilityReporter = new Runnable() {
- private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>();
- private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>();
+ private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
+ new ArraySet<>();
+ private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
+ new ArraySet<>();
+ private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
+ new ArraySet<>();
@Override
public void run() {
mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
+ final String mediaKey = getCurrentMediaNotificationKey();
// 1. Loop over mNotificationData entries:
// A. Keep list of visible notifications.
@@ -518,31 +523,45 @@
for (int i = 0; i < N; i++) {
Entry entry = activeNotifications.get(i);
String key = entry.notification.getKey();
- boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
- boolean currentlyVisible =
+ boolean isVisible =
(mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
- if (currentlyVisible) {
+ NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
+ boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
+ if (isVisible) {
// Build new set of visible notifications.
- mTmpCurrentlyVisibleNotifications.add(key);
- }
- if (!previouslyVisible && currentlyVisible) {
- mTmpNewlyVisibleNotifications.add(key);
+ mTmpCurrentlyVisibleNotifications.add(visObj);
+ if (!previouslyVisible) {
+ mTmpNewlyVisibleNotifications.add(visObj);
+ }
+ } else {
+ // release object
+ visObj.recycle();
}
}
- ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
- noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
+ mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
+ mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
logNotificationVisibilityChanges(
- mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
+ mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
- mCurrentlyVisibleNotifications.clear();
+ recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
- mTmpNewlyVisibleNotifications.clear();
+ recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
mTmpCurrentlyVisibleNotifications.clear();
+ mTmpNewlyVisibleNotifications.clear();
+ mTmpNoLongerVisibleNotifications.clear();
}
};
+ private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
+ final int N = array.size();
+ for (int i = 0 ; i < N; i++) {
+ array.valueAt(i).recycle();
+ }
+ array.clear();
+ }
+
private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -1028,6 +1047,7 @@
private int mShowSearchHoldoff = 0;
private Runnable mInvokeAssist = new Runnable() {
public void run() {
+ mAssistManager.prepareBeforeInvocation();
invokeAssistGesture(true /* vibrate */);
awakenDreams();
if (mNavigationBarView != null) {
@@ -2917,6 +2937,7 @@
updateNotifications();
resetUserSetupObserver();
setControllerUsers();
+ mAssistManager.onUserSwitched(newUserId);
}
private void setControllerUsers() {
@@ -2987,9 +3008,9 @@
// Report all notifications as invisible and turn down the
// reporter.
if (!mCurrentlyVisibleNotifications.isEmpty()) {
- logNotificationVisibilityChanges(
- Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
- mCurrentlyVisibleNotifications.clear();
+ logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
+ mCurrentlyVisibleNotifications);
+ recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
}
mHandler.removeCallbacks(mVisibilityReporter);
mStackScroller.setChildLocationsChangedListener(null);
@@ -3007,18 +3028,27 @@
}
private void logNotificationVisibilityChanges(
- Collection<String> newlyVisible, Collection<String> noLongerVisible) {
+ Collection<NotificationVisibility> newlyVisible,
+ Collection<NotificationVisibility> noLongerVisible) {
if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
return;
}
- String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
- String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
+ NotificationVisibility[] newlyVisibleAr =
+ newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
+ NotificationVisibility[] noLongerVisibleAr =
+ noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
try {
mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
} catch (RemoteException e) {
// Ignore.
}
- setNotificationsShown(newlyVisibleAr);
+
+ final int N = newlyVisible.size();
+ String[] newlyVisibleKeyAr = new String[N];
+ for (int i = 0; i < N; i++) {
+ newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
+ }
+ setNotificationsShown(newlyVisibleKeyAr);
}
// State logging
@@ -3886,6 +3916,7 @@
mScreenOnComingFromTouch = true;
mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
mNotificationPanel.setTouchDisabled(false);
+ mStatusBarKeyguardViewManager.notifyScreenWakeUpRequested();
}
}
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 fcf3a9c..a7e8406 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -73,6 +73,7 @@
private boolean mLastBouncerShowing;
private boolean mLastBouncerDismissible;
private OnDismissAction mAfterKeyguardGoneAction;
+ private boolean mScreenWillWakeUp;
public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils) {
@@ -163,6 +164,7 @@
public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
mScreenOn = true;
+ mScreenWillWakeUp = false;
mPhoneStatusBar.onScreenTurnedOn();
if (callback != null) {
callbackAfterDraw(callback);
@@ -182,6 +184,10 @@
});
}
+ public void notifyScreenWakeUpRequested() {
+ mScreenWillWakeUp = !mScreenOn;
+ }
+
public void verifyUnlock() {
dismiss();
}
@@ -297,7 +303,7 @@
* Dismisses the keyguard by going to the next screen or making it gone.
*/
public void dismiss() {
- if (mScreenOn) {
+ if (mScreenOn || mScreenWillWakeUp) {
showBouncer();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 0aa0b4a..b21767b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -191,6 +191,7 @@
} else {
mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
}
+ mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.FOUR_G);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
index 2b76c31..a5b244e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
@@ -150,13 +150,23 @@
}
public void onStartDrag() {
- mDropTarget.setVisibility(View.VISIBLE);
- mAddTarget.setVisibility(View.GONE);
+ mDropTarget.post(new Runnable() {
+ @Override
+ public void run() {
+ mDropTarget.setVisibility(View.VISIBLE);
+ mAddTarget.setVisibility(View.GONE);
+ }
+ });
}
public void stopDrag() {
- mDropTarget.setVisibility(View.GONE);
- mAddTarget.setVisibility(View.VISIBLE);
+ mDropTarget.post(new Runnable() {
+ @Override
+ public void run() {
+ mDropTarget.setVisibility(View.GONE);
+ mAddTarget.setVisibility(View.VISIBLE);
+ }
+ });
}
@Override
@@ -230,9 +240,16 @@
public void showAddDialog() {
List<String> tiles = mTileSpecs;
+ int numBroadcast = 0;
+ for (int i = 0; i < tiles.size(); i++) {
+ if (tiles.get(i).startsWith(IntentTile.PREFIX)) {
+ numBroadcast++;
+ }
+ }
String[] defaults =
getContext().getString(R.string.quick_settings_tiles_default).split(",");
- final String[] available = new String[defaults.length + 1 - tiles.size()];
+ final String[] available = new String[defaults.length + 1
+ - (tiles.size() - numBroadcast)];
final String[] availableTiles = new String[available.length];
int index = 0;
for (int i = 0; i < defaults.length; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 5b2eb84..065523f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -155,6 +155,7 @@
lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
lp.gravity = Gravity.TOP;
window.setAttributes(lp);
+ window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
mActiveSliderTint = loadColorStateList(R.color.system_accent_color);
mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
@@ -670,6 +671,14 @@
}
private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
+ if (isActive && mExpanded) {
+ row.slider.setFocusable(true);
+ row.slider.setFocusableInTouchMode(true);
+ row.slider.requestFocus();
+ } else {
+ row.slider.setFocusableInTouchMode(false);
+ row.slider.setFocusable(false);
+ }
final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
: mInactiveSliderTint;
if (tint == row.cachedSliderTint) return;
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index f9f6714..25f8872 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
@@ -61,7 +62,7 @@
import java.util.Map;
class BluetoothManagerService extends IBluetoothManager.Stub {
private static final String TAG = "BluetoothManagerService";
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
@@ -114,6 +115,13 @@
private static final int SERVICE_IBLUETOOTH = 1;
private static final int SERVICE_IBLUETOOTHGATT = 2;
+ private static final String[] DEVICE_TYPE_NAMES = new String[] {
+ "???",
+ "BR/EDR",
+ "LE",
+ "DUAL"
+ };
+
private final Context mContext;
private static int mBleAppCount = 0;
@@ -227,21 +235,23 @@
}
}
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ if (DBG) Log.d(TAG, "Bluetooth user switched");
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_USER_SWITCHED,
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ if (DBG) Log.d(TAG, "Bluetooth boot completed");
synchronized(mReceiver) {
if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
//Enable
if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
sendEnableMsg(mQuietEnableExternal);
}
- }
-
- if (!isNameAndAddressSet()) {
- // Sync the Bluetooth name and address from the Bluetooth Adapter
- if (DBG) Log.d(TAG,"Retrieving Bluetooth Adapter name and address...");
- getNameAndAddress();
+ if (!isNameAndAddressSet()) {
+ // Sync the Bluetooth name and address from the
+ // Bluetooth Adapter
+ if (DBG) Log.d(TAG, "Retrieving Bluetooth Adapter name and address...");
+ getNameAndAddress();
+ }
}
}
}
@@ -1099,7 +1109,7 @@
boolean unbind = false;
if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
synchronized(mConnection) {
- if (!mEnable && mBluetooth != null) {
+ if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
try {
mBluetooth.enable();
} catch (RemoteException e) {
@@ -1107,7 +1117,7 @@
}
}
}
- if (mBluetooth != null) waitForOnOff(true, false);
+ if (mBluetooth != null && !mConnection.isGetNameAddressOnly()) waitForOnOff(true, false);
synchronized(mConnection) {
if (mBluetooth != null) {
String name = null;
@@ -1137,7 +1147,7 @@
}
}
}
- if (!mEnable) {
+ if (!mEnable && !mConnection.isGetNameAddressOnly()) {
try {
mBluetooth.disable();
} catch (RemoteException e) {
@@ -1152,7 +1162,9 @@
mHandler.sendMessage(getMsg);
}
}
- if (!mEnable && mBluetooth != null) waitForOnOff(false, true);
+ if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
+ waitForOnOff(false, true);
+ }
if (unbind) {
unbindAndFinish();
}
@@ -1797,6 +1809,14 @@
} else {
ParcelFileDescriptor pfd = null;
try {
+ writer.println("Bonded devices:");
+ for (BluetoothDevice device : mBluetooth.getBondedDevices()) {
+ writer.println(" " + device.getAddress() +
+ " [" + DEVICE_TYPE_NAMES[device.getType()] + "] " +
+ device.getName());
+ }
+ writer.flush();
+
pfd = ParcelFileDescriptor.dup(fd);
mBluetooth.dump(pfd);
} catch (RemoteException re) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 25d4d5e..e4f3f49 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -23,6 +23,7 @@
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
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;
@@ -1559,7 +1560,7 @@
NetworkCapabilities.TRANSPORT_WIFI)) {
timeout = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
- 5);
+ 15);
type = ConnectivityManager.TYPE_WIFI;
} else {
// do not track any other networks
@@ -1869,7 +1870,14 @@
if (nai == null) {
loge("EVENT_NETWORK_CAPABILITIES_CHANGED from unknown NetworkAgent");
} else {
- updateCapabilities(nai, (NetworkCapabilities)msg.obj);
+ final NetworkCapabilities networkCapabilities =
+ (NetworkCapabilities)msg.obj;
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) ||
+ networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
+ Slog.wtf(TAG, "BUG: " + nai + " has stateful capability.");
+ }
+ updateCapabilities(nai, networkCapabilities,
+ NascentState.NOT_JUST_VALIDATED);
}
break;
}
@@ -1956,20 +1964,16 @@
if (isLiveNetworkAgent(nai, "EVENT_NETWORK_TESTED")) {
final boolean valid =
(msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
- final boolean validationChanged = (valid != nai.lastValidated);
- nai.lastValidated = valid;
- if (valid) {
- if (DBG) log("Validated " + nai.name());
- nai.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
- if (!nai.everValidated) {
- nai.everValidated = true;
- rematchNetworkAndRequests(nai, NascentState.JUST_VALIDATED,
- ReapUnvalidatedNetworks.REAP);
- // If score has changed, rebroadcast to NetworkFactories. b/17726566
- sendUpdatedScoreToFactories(nai);
- }
- } else {
- nai.networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);
+ if (DBG) log(nai.name() + " validation " + (valid ? " passed" : "failed"));
+ if (valid != nai.lastValidated) {
+ final int oldScore = nai.getCurrentScore();
+ final NascentState nascent = (valid && !nai.everValidated) ?
+ NascentState.JUST_VALIDATED : NascentState.NOT_JUST_VALIDATED;
+ nai.lastValidated = valid;
+ nai.everValidated |= valid;
+ updateCapabilities(nai, nai.networkCapabilities, nascent);
+ // If score has changed, rebroadcast to NetworkFactories. b/17726566
+ if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
}
updateInetCondition(nai);
// Let the NetworkAgent know the state of its network
@@ -1977,10 +1981,6 @@
android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS,
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
0, null);
-
- if (validationChanged) {
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
}
break;
}
@@ -1993,18 +1993,25 @@
}
case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
final int netId = msg.arg2;
- if (msg.arg1 == 0) {
+ final boolean visible = (msg.arg1 != 0);
+ final NetworkAgentInfo nai;
+ synchronized (mNetworkForNetId) {
+ nai = mNetworkForNetId.get(netId);
+ }
+ // If captive portal status has changed, update capabilities.
+ if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
+ nai.lastCaptivePortalDetected = visible;
+ nai.everCaptivePortalDetected |= visible;
+ updateCapabilities(nai, nai.networkCapabilities,
+ NascentState.NOT_JUST_VALIDATED);
+ }
+ if (!visible) {
setProvNotificationVisibleIntent(false, netId, null, 0, null, null);
} else {
- final NetworkAgentInfo nai;
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(netId);
- }
if (nai == null) {
loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
break;
}
- nai.captivePortalDetected = true;
setProvNotificationVisibleIntent(true, netId, NotificationType.SIGN_IN,
nai.networkInfo.getType(),nai.networkInfo.getExtraInfo(),
(PendingIntent)msg.obj);
@@ -2390,7 +2397,7 @@
if (accept != nai.networkMisc.acceptUnvalidated) {
int oldScore = nai.getCurrentScore();
nai.networkMisc.acceptUnvalidated = accept;
- rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests(nai, oldScore, NascentState.NOT_JUST_VALIDATED);
sendUpdatedScoreToFactories(nai);
}
@@ -2426,7 +2433,7 @@
// Only prompt if the network is unvalidated and was explicitly selected by the user, and if
// we haven't already been told to switch to it regardless of whether it validated or not.
// Also don't prompt on captive portals because we're already prompting the user to sign in.
- if (nai == null || nai.everValidated || nai.captivePortalDetected ||
+ if (nai == null || nai.everValidated || nai.everCaptivePortalDetected ||
!nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
return;
}
@@ -3571,12 +3578,24 @@
}
}
+ private void ensureImmutableCapabilities(NetworkCapabilities networkCapabilities) {
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
+ throw new IllegalArgumentException(
+ "Cannot request network with NET_CAPABILITY_VALIDATED");
+ }
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
+ throw new IllegalArgumentException(
+ "Cannot request network with NET_CAPABILITY_CAPTIVE_PORTAL");
+ }
+ }
+
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
+ ensureImmutableCapabilities(networkCapabilities);
if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) {
throw new IllegalArgumentException("Bad timeout specified");
@@ -3645,6 +3664,7 @@
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
+ ensureImmutableCapabilities(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId());
@@ -4046,18 +4066,35 @@
mNumDnsEntries = last;
}
+ /**
+ * Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities}
+ * augmented with any stateful capabilities implied from {@code networkAgent}
+ * (e.g., validated status and captive portal status).
+ *
+ * @param networkAgent the network having its capabilities updated.
+ * @param networkCapabilities the new network capabilities.
+ * @param nascent indicates whether {@code networkAgent} was validated
+ * (i.e. had everValidated set for the first time) immediately prior to this call.
+ */
private void updateCapabilities(NetworkAgentInfo networkAgent,
- NetworkCapabilities networkCapabilities) {
+ NetworkCapabilities networkCapabilities, NascentState nascent) {
+ // Don't modify caller's NetworkCapabilities.
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ if (networkAgent.lastValidated) {
+ networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
+ } else {
+ networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);
+ }
+ if (networkAgent.lastCaptivePortalDetected) {
+ networkCapabilities.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+ } else {
+ networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
+ }
if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
synchronized (networkAgent) {
networkAgent.networkCapabilities = networkCapabilities;
}
- if (networkAgent.lastValidated) {
- networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
- // There's no need to remove the capability if we think the network is unvalidated,
- // because NetworkAgents don't set the validated capability.
- }
- rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore());
+ rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore(), nascent);
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
}
@@ -4401,15 +4438,21 @@
}
}
- // Attempt to rematch all Networks with NetworkRequests. This may result in Networks
- // being disconnected.
- // If only one Network's score or capabilities have been modified since the last time
- // this function was called, pass this Network in via the "changed" arugment, otherwise
- // pass null.
- // If only one Network has been changed but its NetworkCapabilities have not changed,
- // pass in the Network's score (from getCurrentScore()) prior to the change via
- // "oldScore", otherwise pass changed.getCurrentScore() or 0 if "changed" is null.
- private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
+ /**
+ * Attempt to rematch all Networks with NetworkRequests. This may result in Networks
+ * being disconnected.
+ * @param changed If only one Network's score or capabilities have been modified since the last
+ * time this function was called, pass this Network in this argument, otherwise pass
+ * null.
+ * @param oldScore If only one Network has been changed but its NetworkCapabilities have not
+ * changed, pass in the Network's score (from getCurrentScore()) prior to the change via
+ * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if
+ * {@code changed} is {@code null}. This is because NetworkCapabilities influence a
+ * network's score.
+ * @param nascent indicates if {@code changed} has just been validated.
+ */
+ private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore,
+ NascentState nascent) {
// TODO: This may get slow. The "changed" parameter is provided for future optimization
// to avoid the slowness. It is not simply enough to process just "changed", for
// example in the case where "changed"'s score decreases and another network should begin
@@ -4418,9 +4461,9 @@
// Optimization: Only reprocess "changed" if its score improved. This is safe because it
// can only add more NetworkRequests satisfied by "changed", and this is exactly what
// rematchNetworkAndRequests() handles.
- if (changed != null && oldScore < changed.getCurrentScore()) {
- rematchNetworkAndRequests(changed, NascentState.NOT_JUST_VALIDATED,
- ReapUnvalidatedNetworks.REAP);
+ if (changed != null &&
+ (oldScore < changed.getCurrentScore() || nascent == NascentState.JUST_VALIDATED)) {
+ rematchNetworkAndRequests(changed, nascent, ReapUnvalidatedNetworks.REAP);
} else {
for (Iterator i = mNetworkAgentInfos.values().iterator(); i.hasNext(); ) {
rematchNetworkAndRequests((NetworkAgentInfo)i.next(),
@@ -4547,7 +4590,7 @@
final int oldScore = nai.getCurrentScore();
nai.setCurrentScore(score);
- rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests(nai, oldScore, NascentState.NOT_JUST_VALIDATED);
sendUpdatedScoreToFactories(nai);
}
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 82b334a..dc203ff 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -97,9 +97,6 @@
private static final String ACTION_STEP_IDLE_STATE =
"com.android.server.device_idle.STEP_IDLE_STATE";
- private static final String ACTION_ENTER_INACTIVE_STATE =
- "com.android.server.device_idle.ENTER_INACTIVE_STATE";
-
private AlarmManager mAlarmManager;
private IBatteryStats mBatteryStats;
private PowerManagerInternal mLocalPowerManager;
@@ -112,7 +109,7 @@
private Intent mIdleIntent;
private Display mCurDisplay;
private AnyMotionDetector mAnyMotionDetector;
- private boolean mIdleDisabled;
+ private boolean mEnabled;
private boolean mScreenOn;
private boolean mCharging;
private boolean mSigMotionActive;
@@ -191,10 +188,6 @@
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
}
- } else if (ACTION_ENTER_INACTIVE_STATE.equals(intent.getAction())) {
- synchronized (DeviceIdleController.this) {
- enterInactiveStateLocked();
- }
}
}
};
@@ -612,6 +605,8 @@
final PackageManager pm = getContext().getPackageManager();
synchronized (this) {
+ mEnabled = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_enableAutoPowerModes);
SystemConfig sysConfig = SystemConfig.getInstance();
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
for (int i=0; i<allowPower.size(); i++) {
@@ -881,7 +876,7 @@
void becomeInactiveIfAppropriateLocked() {
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
- if (!mScreenOn && !mCharging && !mIdleDisabled && mState == STATE_ACTIVE) {
+ if (!mScreenOn && !mCharging && mEnabled && mState == STATE_ACTIVE) {
// Screen has turned off; we are now going to become inactive and start
// waiting to see if we will ultimately go idle.
mState = STATE_INACTIVE;
@@ -1216,8 +1211,12 @@
pw.println(" Completely disable device idle mode.");
pw.println(" enable");
pw.println(" Re-enable device idle mode after it had previously been disabled.");
- pw.println(" whitelist");
+ pw.println(" enabled");
+ pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
+ pw.println(" whitelist [package ...]");
pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
+ pw.println(" tempwhitelist [package ..]");
+ pw.println(" Temporarily place packages in whitelist for 10 seconds.");
}
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1252,8 +1251,8 @@
return;
} else if ("disable".equals(arg)) {
synchronized (this) {
- if (!mIdleDisabled) {
- mIdleDisabled = true;
+ if (mEnabled) {
+ mEnabled = false;
becomeActiveLocked("disabled", Process.myUid());
pw.println("Idle mode disabled");
}
@@ -1261,13 +1260,18 @@
return;
} else if ("enable".equals(arg)) {
synchronized (this) {
- if (mIdleDisabled) {
- mIdleDisabled = false;
+ if (!mEnabled) {
+ mEnabled = true;
becomeInactiveIfAppropriateLocked();
pw.println("Idle mode enabled");
}
}
return;
+ } else if ("enabled".equals(arg)) {
+ synchronized (this) {
+ pw.println(mEnabled ? "1" : " 0");
+ }
+ return;
} else if ("whitelist".equals(arg)) {
i++;
while (i < args.length) {
@@ -1364,9 +1368,9 @@
}
}
+ pw.print(" mEnabled="); pw.println(mEnabled);
pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor);
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
- pw.print(" mIdleDisabled="); pw.println(mIdleDisabled);
pw.print(" mScreenOn="); pw.println(mScreenOn);
pw.print(" mCharging="); pw.println(mCharging);
pw.print(" mSigMotionActive="); pw.println(mSigMotionActive);
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 49d4c22..43b640b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -74,7 +74,7 @@
# when a notification has been canceled
27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1)
# replaces 27510 with a row per notification
-27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1)
+27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1)
# a notification emited noise, vibration, or light
27532 notification_alert (key|3),(buzz|1),(beep|1),(blink|1)
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 47c9f04..dbe8781 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1043,8 +1043,9 @@
resetAllInternalStateLocked(false /* updateOnlyWhenLocaleChanged */,
initialUserSwitch /* needsToResetDefaultIme */);
if (initialUserSwitch) {
- InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mContext.getPackageManager(),
- mSettings.getEnabledInputMethodListLocked());
+ InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
+ mSettings.getEnabledInputMethodListLocked(), newUserId,
+ mContext.getBasePackageName());
}
if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
@@ -1101,9 +1102,9 @@
if (!mImeSelectedOnBoot) {
Slog.w(TAG, "Reset the default IME as \"Resource\" is ready here.");
resetStateIfCurrentLocaleChangedLocked();
- InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
- mContext.getPackageManager(),
- mSettings.getEnabledInputMethodListLocked());
+ InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
+ mSettings.getEnabledInputMethodListLocked(),
+ mSettings.getCurrentUserId(), mContext.getBasePackageName());
}
mLastSystemLocale = mRes.getConfiguration().locale;
try {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 61bedf5..cae060a 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -270,6 +270,17 @@
};
mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback);
+ PackageManager.OnPermissionsChangedListener permissionListener
+ = new PackageManager.OnPermissionsChangedListener() {
+ @Override
+ public void onPermissionsChanged(final int uid) {
+ synchronized (mLock) {
+ applyAllProviderRequirementsLocked();
+ }
+ }
+ };
+ mPackageManager.addOnPermissionsChangeListener(permissionListener);
+
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
updateUserProfiles(mCurrentUserId);
@@ -1133,23 +1144,34 @@
return -1;
}
- boolean reportLocationAccessNoThrow(int uid, String packageName, int allowedResolutionLevel) {
+ boolean reportLocationAccessNoThrow(
+ int pid, int uid, String packageName, int allowedResolutionLevel) {
int op = resolutionLevelToOp(allowedResolutionLevel);
if (op >= 0) {
if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
return false;
}
}
+
+ if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
+ return false;
+ }
+
return true;
}
- boolean checkLocationAccess(int uid, String packageName, int allowedResolutionLevel) {
+ boolean checkLocationAccess(int pid, int uid, String packageName, int allowedResolutionLevel) {
int op = resolutionLevelToOp(allowedResolutionLevel);
if (op >= 0) {
if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
return false;
}
}
+
+ if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
+ return false;
+ }
+
return true;
}
@@ -1347,7 +1369,10 @@
if (records != null) {
for (UpdateRecord record : records) {
if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) {
- if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName,
+ if (checkLocationAccess(
+ record.mReceiver.mPid,
+ record.mReceiver.mUid,
+ record.mReceiver.mPackageName,
record.mReceiver.mAllowedResolutionLevel)) {
LocationRequest locationRequest = record.mRequest;
providerRequest.locationRequests.add(locationRequest);
@@ -1583,7 +1608,7 @@
try {
// We don't check for MODE_IGNORED here; we will do that when we go to deliver
// a location.
- checkLocationAccess(uid, packageName, allowedResolutionLevel);
+ checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
synchronized (mLock) {
Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
@@ -1711,6 +1736,7 @@
request.getProvider());
// no need to sanitize this request, as only the provider name is used
+ final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long identity = Binder.clearCallingIdentity();
try {
@@ -1720,7 +1746,7 @@
return null;
}
- if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) {
+ if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel)) {
if (D) Log.d(TAG, "not returning last loc for no op app: " +
packageName);
return null;
@@ -1794,7 +1820,6 @@
@Override
public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) {
- checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel());
checkPendingIntent(intent);
checkPackageName(packageName);
@@ -1816,10 +1841,11 @@
checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
LocationManager.GPS_PROVIDER);
+ final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- if (!checkLocationAccess(uid, packageName, allowedResolutionLevel)) {
+ if (!checkLocationAccess(pid, uid, packageName, allowedResolutionLevel)) {
return false;
}
} finally {
@@ -1859,11 +1885,12 @@
allowedResolutionLevel,
LocationManager.GPS_PROVIDER);
+ int pid = Binder.getCallingPid();
int uid = Binder.getCallingUid();
long identity = Binder.clearCallingIdentity();
boolean hasLocationAccess;
try {
- hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel);
+ hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1890,11 +1917,12 @@
allowedResolutionLevel,
LocationManager.GPS_PROVIDER);
+ int pid = Binder.getCallingPid();
int uid = Binder.getCallingUid();
long identity = Binder.clearCallingIdentity();
boolean hasLocationAccess;
try {
- hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel);
+ hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2209,7 +2237,7 @@
continue;
}
- if (!reportLocationAccessNoThrow(receiver.mUid, receiver.mPackageName,
+ if (!reportLocationAccessNoThrow(receiver.mPid, receiver.mUid, receiver.mPackageName,
receiver.mAllowedResolutionLevel)) {
if (D) Log.d(TAG, "skipping loc update for no op app: " +
receiver.mPackageName);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 5436ce0..c5ea8bc 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -27,11 +27,10 @@
import android.content.pm.UserInfo;
import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.content.Context.USER_SERVICE;
-import static android.Manifest.permission.READ_PROFILE;
+import static android.Manifest.permission.READ_CONTACTS;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;
-import android.os.Process;
import android.os.RemoteException;
import android.os.storage.IMountService;
import android.os.ServiceManager;
@@ -264,12 +263,12 @@
private final void checkReadPermission(String requestedKey, int userId) {
final int callingUid = Binder.getCallingUid();
- for (int i = 0; i < READ_PROFILE_PROTECTED_SETTINGS.length; i++) {
- String key = READ_PROFILE_PROTECTED_SETTINGS[i];
- if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_PROFILE)
+ for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
+ String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
+ if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("uid=" + callingUid
- + " needs permission " + READ_PROFILE + " to read "
+ + " needs permission " + READ_CONTACTS + " to read "
+ requestedKey + " for user " + userId);
}
}
@@ -722,8 +721,8 @@
Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
};
- // Reading these settings needs the profile permission
- private static final String[] READ_PROFILE_PROTECTED_SETTINGS = new String[] {
+ // Reading these settings needs the contacts permission
+ private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
Secure.LOCK_SCREEN_OWNER_INFO
};
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 34dceed..7204aec 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -259,6 +259,7 @@
private static final String TAG_VOLUME = "volume";
private static final String ATTR_TYPE = "type";
private static final String ATTR_FS_UUID = "fsUuid";
+ private static final String ATTR_PART_GUID = "partGuid";
private static final String ATTR_NICKNAME = "nickname";
private static final String ATTR_USER_FLAGS = "userFlags";
@@ -689,7 +690,7 @@
// Create a stub volume that represents internal storage
final VolumeInfo internal = new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL,
- VolumeInfo.TYPE_PRIVATE, null, 0);
+ VolumeInfo.TYPE_PRIVATE, null, null, 0);
internal.state = VolumeInfo.STATE_MOUNTED;
internal.path = Environment.getDataDirectory().getAbsolutePath();
mVolumes.put(internal.id, internal);
@@ -900,10 +901,12 @@
case VoldResponseCode.VOLUME_CREATED: {
final String id = cooked[1];
final int type = Integer.parseInt(cooked[2]);
- final String diskId = (cooked.length == 4) ? cooked[3] : null;
+ final String diskId = TextUtils.nullIfEmpty(cooked[3]);
+ final String partGuid = TextUtils.nullIfEmpty(cooked[4]);
+
final DiskInfo disk = mDisks.get(diskId);
final int mtpIndex = allocateMtpIndex(id);
- final VolumeInfo vol = new VolumeInfo(id, type, disk, mtpIndex);
+ final VolumeInfo vol = new VolumeInfo(id, type, disk, partGuid, mtpIndex);
mVolumes.put(id, vol);
onVolumeCreatedLocked(vol);
break;
@@ -1091,13 +1094,21 @@
// Remember that we saw this volume so we're ready to accept user
// metadata, or so we can annoy them when a private volume is ejected
if (vol.isMountedReadable() && !TextUtils.isEmpty(vol.fsUuid)) {
- if (!mRecords.containsKey(vol.fsUuid)) {
- final VolumeRecord rec = new VolumeRecord(vol.type, vol.fsUuid);
+ VolumeRecord rec = mRecords.get(vol.fsUuid);
+ if (rec == null) {
+ rec = new VolumeRecord(vol.type, vol.fsUuid);
+ rec.partGuid = vol.partGuid;
if (vol.type == VolumeInfo.TYPE_PRIVATE) {
rec.nickname = vol.disk.getDescription();
}
mRecords.put(rec.fsUuid, rec);
writeSettingsLocked();
+ } else {
+ // Handle upgrade case where we didn't store partition GUID
+ if (TextUtils.isEmpty(rec.partGuid)) {
+ rec.partGuid = vol.partGuid;
+ writeSettingsLocked();
+ }
}
}
@@ -1347,6 +1358,7 @@
final int type = readIntAttribute(in, ATTR_TYPE);
final String fsUuid = readStringAttribute(in, ATTR_FS_UUID);
final VolumeRecord meta = new VolumeRecord(type, fsUuid);
+ meta.partGuid = readStringAttribute(in, ATTR_PART_GUID);
meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
return meta;
@@ -1356,6 +1368,7 @@
out.startTag(null, TAG_VOLUME);
writeIntAttribute(out, ATTR_TYPE, rec.type);
writeStringAttribute(out, ATTR_FS_UUID, rec.fsUuid);
+ writeStringAttribute(out, ATTR_PART_GUID, rec.partGuid);
writeStringAttribute(out, ATTR_NICKNAME, rec.nickname);
writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags);
out.endTag(null, TAG_VOLUME);
@@ -1491,6 +1504,8 @@
try {
final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId);
return Long.parseLong(res.getMessage());
+ } catch (NativeDaemonTimeoutException e) {
+ return Long.MAX_VALUE;
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -1573,9 +1588,11 @@
Preconditions.checkNotNull(fsUuid);
synchronized (mLock) {
- mRecords.remove(fsUuid);
-
- // TODO: tell vold to forget keys
+ final VolumeRecord rec = mRecords.remove(fsUuid);
+ if (rec != null && !TextUtils.isEmpty(rec.partGuid)) {
+ forgetPartition(rec.partGuid);
+ }
+ mCallbacks.notifyVolumeForgotten(fsUuid);
// If this had been primary storage, revert back to internal and
// reset vold so we bind into new volume into place.
@@ -1584,7 +1601,6 @@
resetIfReadyAndConnected();
}
- mCallbacks.notifyVolumeForgotten(fsUuid);
writeSettingsLocked();
}
}
@@ -1597,6 +1613,10 @@
synchronized (mLock) {
for (int i = 0; i < mRecords.size(); i++) {
final String fsUuid = mRecords.keyAt(i);
+ final VolumeRecord rec = mRecords.valueAt(i);
+ if (!TextUtils.isEmpty(rec.partGuid)) {
+ forgetPartition(rec.partGuid);
+ }
mCallbacks.notifyVolumeForgotten(fsUuid);
}
mRecords.clear();
@@ -1610,6 +1630,14 @@
}
}
+ private void forgetPartition(String partGuid) {
+ try {
+ mConnector.execute("volume", "forget_partition", partGuid);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.w(TAG, "Failed to forget key for " + partGuid + ": " + e);
+ }
+ }
+
@Override
public void setDebugFlags(int flags, int mask) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index 78c7f38..e7979e4 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -421,7 +421,7 @@
event = mResponseQueue.remove(sequenceNumber, timeout, logCmd);
if (event == null) {
loge("timed-out waiting for response to " + logCmd);
- throw new NativeDaemonFailureException(logCmd, event);
+ throw new NativeDaemonTimeoutException(logCmd, event);
}
if (VDBG) log("RMV <- {" + event + "}");
events.add(event);
diff --git a/core/java/android/view/ViewAssistStructure.java b/services/core/java/com/android/server/NativeDaemonTimeoutException.java
similarity index 64%
copy from core/java/android/view/ViewAssistStructure.java
copy to services/core/java/com/android/server/NativeDaemonTimeoutException.java
index a66d93c..658f7d6 100644
--- a/core/java/android/view/ViewAssistStructure.java
+++ b/services/core/java/com/android/server/NativeDaemonTimeoutException.java
@@ -14,11 +14,15 @@
* limitations under the License.
*/
-package android.view;
+package com.android.server;
/**
- * @deprecated Temporary until old apps can move off this.
+ * An exception that indicates there was a timeout with a
+ * {@link NativeDaemonConnector} operation.
*/
-@Deprecated
-public abstract class ViewAssistStructure extends ViewStructure {
+public class NativeDaemonTimeoutException extends NativeDaemonConnectorException {
+ public NativeDaemonTimeoutException(String command, NativeDaemonEvent event) {
+ super(command, event);
+ }
}
+
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index baa55e7..7afb192 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -214,9 +214,9 @@
*/
@GuardedBy("mQuotaLock")
private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
-
- private boolean mStandbyChainEnabled = false;
- private boolean mDozableChainEnabled = false;
+ /** Set of states for the child firewall chains. True if the chain is active. */
+ @GuardedBy("mQuotaLock")
+ final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
private Object mIdleTimerLock = new Object();
/** Set of interfaces with active idle timers. */
@@ -307,9 +307,6 @@
}
public void systemReady() {
- // init firewall states
- mDozableChainEnabled = false;
- mStandbyChainEnabled = true;
prepareNativeDaemon();
if (DBG) Slog.d(TAG, "Prepared");
}
@@ -611,7 +608,7 @@
uidFirewallRules.valueAt(i));
}
}
- if (mStandbyChainEnabled) {
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)) {
setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true);
}
@@ -625,7 +622,7 @@
uidFirewallRules.valueAt(i));
}
}
- if (mDozableChainEnabled) {
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)) {
setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true);
}
}
@@ -2013,24 +2010,31 @@
@Override
public void setFirewallChainEnabled(int chain, boolean enable) {
enforceSystemUid();
- final String operation = enable ? "enable_chain" : "disable_chain";
- try {
- String chainName;
- switch(chain) {
- case FIREWALL_CHAIN_STANDBY:
- chainName = FIREWALL_CHAIN_NAME_STANDBY;
- mStandbyChainEnabled = enable;
- break;
- case FIREWALL_CHAIN_DOZABLE:
- chainName = FIREWALL_CHAIN_NAME_DOZABLE;
- mDozableChainEnabled = enable;
- break;
- default:
- throw new IllegalArgumentException("Bad child chain: " + chain);
+ synchronized (mQuotaLock) {
+ if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
+ mFirewallChainStates.get(chain) == enable) {
+ // All is the same, nothing to do.
+ return;
}
- mConnector.execute("firewall", operation, chainName);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mFirewallChainStates.put(chain, enable);
+
+ final String operation = enable ? "enable_chain" : "disable_chain";
+ try {
+ String chainName;
+ switch(chain) {
+ case FIREWALL_CHAIN_STANDBY:
+ chainName = FIREWALL_CHAIN_NAME_STANDBY;
+ break;
+ case FIREWALL_CHAIN_DOZABLE:
+ chainName = FIREWALL_CHAIN_NAME_DOZABLE;
+ break;
+ default:
+ throw new IllegalArgumentException("Bad child chain: " + chain);
+ }
+ mConnector.execute("firewall", operation, chainName);
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
}
}
@@ -2048,27 +2052,29 @@
@Override
public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
enforceSystemUid();
- SparseIntArray uidFirewallRules = getUidFirewallRules(chain);
- SparseIntArray newRules = new SparseIntArray();
- // apply new set of rules
- for (int index = uids.length - 1; index >= 0; --index) {
- int uid = uids[index];
- int rule = rules[index];
- setFirewallUidRule(chain, uid, rule);
- newRules.put(uid, rule);
- }
- // collect the rules to remove.
- SparseIntArray rulesToRemove = new SparseIntArray();
- for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
- int uid = uidFirewallRules.keyAt(index);
- if (newRules.indexOfKey(uid) < 0) {
- rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
+ synchronized (mQuotaLock) {
+ SparseIntArray uidFirewallRules = getUidFirewallRules(chain);
+ SparseIntArray newRules = new SparseIntArray();
+ // apply new set of rules
+ for (int index = uids.length - 1; index >= 0; --index) {
+ int uid = uids[index];
+ int rule = rules[index];
+ setFirewallUidRule(chain, uid, rule);
+ newRules.put(uid, rule);
}
- }
- // remove dead rules
- for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
- int uid = rulesToRemove.keyAt(index);
- setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT);
+ // collect the rules to remove.
+ SparseIntArray rulesToRemove = new SparseIntArray();
+ for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
+ int uid = uidFirewallRules.keyAt(index);
+ if (newRules.indexOfKey(uid) < 0) {
+ rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
+ }
+ }
+ // remove dead rules
+ for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
+ int uid = rulesToRemove.keyAt(index);
+ setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT);
+ }
}
}
@@ -2094,34 +2100,43 @@
}
try {
- String ruleName;
- if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
- if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
- ruleName = "allow";
- } else {
- ruleName = "deny";
- }
- } else { // Blacklist mode
- if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) {
- ruleName = "deny";
- } else {
- ruleName = "allow";
- }
- }
+ String ruleName = getFirewallRuleName(chain, rule);
+ String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule);
if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
uidFirewallRules.delete(uid);
} else {
uidFirewallRules.put(uid, rule);
}
- mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid,
- ruleName);
+
+ if (!ruleName.equals(oldRuleName)) {
+ mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid,
+ ruleName);
+ }
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
}
+ private @NonNull String getFirewallRuleName(int chain, int rule) {
+ String ruleName;
+ if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
+ if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
+ ruleName = "allow";
+ } else {
+ ruleName = "deny";
+ }
+ } else { // Blacklist mode
+ if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) {
+ ruleName = "deny";
+ } else {
+ ruleName = "allow";
+ }
+ }
+ return ruleName;
+ }
+
private @NonNull SparseIntArray getUidFirewallRules(int chain) {
switch (chain) {
case FIREWALL_CHAIN_STANDBY:
@@ -2272,7 +2287,8 @@
pw.println("]");
}
- pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled);
+ pw.println("UID firewall standby chain enabled: " +
+ mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY));
synchronized (mUidFirewallStandbyRules) {
pw.print("UID firewall standby rule: [");
final int size = mUidFirewallStandbyRules.size();
@@ -2285,7 +2301,8 @@
pw.println("]");
}
- pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled);
+ pw.println("UID firewall dozable chain enabled: " +
+ mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE));
synchronized (mUidFirewallDozableRules) {
pw.print("UID firewall dozable rule: [");
final int size = mUidFirewallDozableRules.size();
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 3456dbc..50d311f 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1591,13 +1591,6 @@
try {
final ContentValues values = new ContentValues();
values.put(ACCOUNTS_PASSWORD, password);
- long time = 0;
- // Only set current time, if it is a valid password. For clear password case, it
- // should not be set.
- if (password != null) {
- time = System.currentTimeMillis();
- }
- values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, time);
final long accountId = getAccountIdLocked(db, account);
if (accountId >= 0) {
final String[] argsAccountId = {String.valueOf(accountId)};
@@ -2130,7 +2123,7 @@
try {
new Session(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */, null /* accountName */,
- false /* authDetailsRequired */) {
+ false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) {
@Override
public void run() throws RemoteException {
mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
@@ -2207,7 +2200,7 @@
try {
new Session(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */, null /* accountName */,
- false /* authDetailsRequired */) {
+ false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) {
@Override
public void run() throws RemoteException {
mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
@@ -2940,14 +2933,14 @@
if (result != null) {
boolean isSuccessfulConfirmCreds = result.getBoolean(
AccountManager.KEY_BOOLEAN_RESULT, false);
- boolean isSuccessfulUpdateCreds =
+ boolean isSuccessfulUpdateCredsOrAddAccount =
result.containsKey(AccountManager.KEY_ACCOUNT_NAME)
&& result.containsKey(AccountManager.KEY_ACCOUNT_TYPE);
// We should only update lastAuthenticated time, if
// mUpdateLastAuthenticatedTime is true and the confirmRequest
// or updateRequest was successful
boolean needUpdate = mUpdateLastAuthenticatedTime
- && (isSuccessfulConfirmCreds || isSuccessfulUpdateCreds);
+ && (isSuccessfulConfirmCreds || isSuccessfulUpdateCredsOrAddAccount);
if (needUpdate || mAuthDetailsRequired) {
boolean accountPresent = isAccountPresentForCaller(mAccountName, mAccountType);
if (needUpdate && accountPresent) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c0c401d..1ef1375 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2744,13 +2744,19 @@
return index;
}
+ private static void killProcessGroup(int uid, int pid) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
+ Process.killProcessGroup(uid, pid);
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
final void removeLruProcessLocked(ProcessRecord app) {
int lrui = mLruProcesses.lastIndexOf(app);
if (lrui >= 0) {
if (!app.killed) {
Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
Process.killProcessQuiet(app.pid);
- Process.killProcessGroup(app.info.uid, app.pid);
+ killProcessGroup(app.info.uid, app.pid);
}
if (lrui <= mLruProcessActivityStart) {
mLruProcessActivityStart--;
@@ -3115,7 +3121,7 @@
// clean it up now.
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
checkTime(startTime, "startProcess: bad proc running, killing");
- Process.killProcessGroup(app.info.uid, app.pid);
+ killProcessGroup(app.info.uid, app.pid);
handleAppDiedLocked(app, true, true);
checkTime(startTime, "startProcess: done killing old proc");
}
@@ -4603,7 +4609,7 @@
if (!fromBinderDied) {
Process.killProcessQuiet(pid);
}
- Process.killProcessGroup(app.info.uid, pid);
+ killProcessGroup(app.info.uid, pid);
app.killed = true;
}
@@ -5924,7 +5930,7 @@
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
- //TODO: Process.killProcessGroup(app.info.uid, pid);
+ //TODO: killProcessGroup(app.info.uid, pid);
} else {
try {
thread.scheduleExit();
@@ -10773,15 +10779,21 @@
return;
}
}
- pae.intent.replaceExtras(pae.extras);
- pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_SINGLE_TOP
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- closeSystemDialogs("assist");
+
+ long ident = Binder.clearCallingIdentity();
try {
- mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
- } catch (ActivityNotFoundException e) {
- Slog.w(TAG, "No activity to handle assist action.", e);
+ pae.intent.replaceExtras(pae.extras);
+ pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ closeSystemDialogs("assist");
+ try {
+ mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist action.", e);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
@@ -12392,7 +12404,7 @@
} else {
// Huh.
Process.killProcess(pid);
- Process.killProcessGroup(uid, pid);
+ killProcessGroup(uid, pid);
}
}
return;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 3854e51..78557634 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -38,6 +38,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Slog;
@@ -629,7 +630,10 @@
// Collect data now for the past activity.
synchronized (mStats) {
if (mStats.isOnBattery()) {
- mHandler.scheduleWifiSync("wifi-data");
+ final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH ||
+ powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
+ : "inactive";
+ mHandler.scheduleWifiSync("wifi-data: " + type);
}
mStats.noteWifiRadioPowerState(powerState, tsNanos);
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 3acd3a3..bd31a21 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -40,6 +40,7 @@
import android.os.IBinder;
import android.os.Process;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.PrintWriterPrinter;
@@ -536,6 +537,7 @@
void kill(String reason, boolean noisy) {
if (!killedByAm) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
if (noisy) {
Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
}
@@ -546,6 +548,7 @@
killed = true;
killedByAm = true;
}
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 47d3bde..0dc4076 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3099,10 +3099,13 @@
|| mContext.getResources().getBoolean(
com.android.internal.R.bool.config_safe_media_volume_enabled);
+ boolean safeMediaVolumeBypass =
+ SystemProperties.getBoolean("audio.safemedia.bypass", false);
+
// The persisted state is either "disabled" or "active": this is the state applied
// next time we boot and cannot be "inactive"
int persistedState;
- if (safeMediaVolumeEnabled) {
+ if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
// The state can already be "inactive" here if the user has forced it before
// the 30 seconds timeout for forced configuration. In this case we don't reset
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index 9347c24..0be24f4 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -16,7 +16,10 @@
package com.android.server.camera;
import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.hardware.ICameraService;
import android.hardware.ICameraServiceProxy;
@@ -67,6 +70,32 @@
private final Object mLock = new Object();
private Set<Integer> mEnabledCameraUsers;
+ private int mLastUser;
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action == null) return;
+
+ switch (action) {
+ case Intent.ACTION_USER_ADDED:
+ case Intent.ACTION_USER_REMOVED:
+ case Intent.ACTION_USER_INFO_CHANGED:
+ case Intent.ACTION_MANAGED_PROFILE_ADDED:
+ case Intent.ACTION_MANAGED_PROFILE_REMOVED:
+ synchronized(mLock) {
+ // Return immediately if we haven't seen any users start yet
+ if (mEnabledCameraUsers == null) return;
+ switchUserLocked(mLastUser);
+ }
+ break;
+ default:
+ break; // do nothing
+ }
+
+ }
+ };
private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
@Override
@@ -103,6 +132,15 @@
// Should never see this unless someone messes up the SystemServer service boot order.
throw new IllegalStateException("UserManagerService must start before CameraService!");
}
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+ mContext.registerReceiver(mIntentReceiver, filter);
+
publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy);
}
@@ -125,6 +163,7 @@
private void switchUserLocked(int userHandle) {
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
+ mLastUser = userHandle;
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
mEnabledCameraUsers = currentUserHandles;
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 3bf1183..51c6628 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -45,6 +45,7 @@
// This Network object is always valid.
public final Network network;
public LinkProperties linkProperties;
+ // This should only be modified via ConnectivityService.updateCapabilities().
public NetworkCapabilities networkCapabilities;
public final NetworkMonitor networkMonitor;
public final NetworkMisc networkMisc;
@@ -66,7 +67,10 @@
// Whether a captive portal was ever detected on this network.
// This is a sticky bit; once set it is never cleared.
- public boolean captivePortalDetected;
+ public boolean everCaptivePortalDetected;
+
+ // Whether a captive portal was found during the last network validation attempt.
+ public boolean lastCaptivePortalDetected;
// This represents the last score received from the NetworkAgent.
private int currentScore;
@@ -174,7 +178,8 @@
"created{" + created + "} " +
"explicitlySelected{" + networkMisc.explicitlySelected + "} " +
"acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
- "captivePortalDetected{" + captivePortalDetected + "} " +
+ "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " +
+ "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " +
"}";
}
diff --git a/services/core/java/com/android/server/content/AppIdleMonitor.java b/services/core/java/com/android/server/content/AppIdleMonitor.java
index 9598de8..fe5c2da 100644
--- a/services/core/java/com/android/server/content/AppIdleMonitor.java
+++ b/services/core/java/com/android/server/content/AppIdleMonitor.java
@@ -18,11 +18,6 @@
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
import android.os.UserHandle;
import com.android.server.LocalServices;
@@ -31,53 +26,32 @@
* Helper to listen for app idle and charging status changes and restart backed off
* sync operations.
*/
-class AppIdleMonitor implements AppIdleStateChangeListener {
+class AppIdleMonitor extends AppIdleStateChangeListener {
private final SyncManager mSyncManager;
private final UsageStatsManagerInternal mUsageStats;
- final BatteryManager mBatteryManager;
- /** Is the device currently plugged into power. */
- private boolean mPluggedIn;
+ private boolean mAppIdleParoleOn;
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onPluggedIn(mBatteryManager.isCharging());
- }
- };
-
- AppIdleMonitor(SyncManager syncManager, Context context) {
+ AppIdleMonitor(SyncManager syncManager) {
mSyncManager = syncManager;
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+ mAppIdleParoleOn = mUsageStats.isAppIdleParoleOn();
+
mUsageStats.addAppIdleStateChangeListener(this);
- mBatteryManager = context.getSystemService(BatteryManager.class);
- mPluggedIn = isPowered();
- registerReceivers(context);
}
- private void registerReceivers(Context context) {
- // Monitor battery charging state
- IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING);
- filter.addAction(BatteryManager.ACTION_DISCHARGING);
- context.registerReceiver(mReceiver, filter);
- }
-
- private boolean isPowered() {
- return mBatteryManager.isCharging();
- }
-
- void onPluggedIn(boolean pluggedIn) {
- if (mPluggedIn == pluggedIn) {
+ void setAppIdleParoleOn(boolean appIdleParoleOn) {
+ if (mAppIdleParoleOn == appIdleParoleOn) {
return;
}
- mPluggedIn = pluggedIn;
- if (mPluggedIn) {
+ mAppIdleParoleOn = appIdleParoleOn;
+ if (mAppIdleParoleOn) {
mSyncManager.onAppNotIdle(null, UserHandle.USER_ALL);
}
}
boolean isAppIdle(String packageName, int userId) {
- return !mPluggedIn && mUsageStats.isAppIdle(packageName, userId);
+ return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, userId);
}
@Override
@@ -86,4 +60,9 @@
if (idle) return;
mSyncManager.onAppNotIdle(packageName, userId);
}
+
+ @Override
+ public void onParoleStateChanged(boolean isParoleOn) {
+ setAppIdleParoleOn(isParoleOn);
+ }
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index cd9c7fe..658f6f8 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -19,6 +19,7 @@
import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppGlobals;
@@ -55,6 +56,7 @@
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import android.net.TrafficStats;
import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Handler;
@@ -100,7 +102,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -162,6 +163,19 @@
private static final long ACTIVE_SYNC_TIMEOUT_MILLIS = 30L * 60 * 1000; // 30 mins
/**
+ * How often to periodically poll network traffic for an adapter performing a sync to determine
+ * whether progress is being made.
+ */
+ private static final long SYNC_MONITOR_WINDOW_LENGTH_MILLIS = 60 * 1000; // 60 seconds
+
+ /**
+ * How many bytes must be transferred (Tx + Rx) over the period of time defined by
+ * {@link #SYNC_MONITOR_WINDOW_LENGTH_MILLIS} for the sync to be considered to be making
+ * progress.
+ */
+ private static final int SYNC_MONITOR_PROGRESS_THRESHOLD_BYTES = 10; // 10 bytes
+
+ /**
* How long to delay each queued {@link SyncHandler} message that may have occurred before boot
* or befor the device became provisioned.
*/
@@ -448,7 +462,7 @@
mSyncAlarmIntent = PendingIntent.getBroadcast(
mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0);
- mAppIdleMonitor = new AppIdleMonitor(this, mContext);
+ mAppIdleMonitor = new AppIdleMonitor(this);
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
@@ -957,20 +971,42 @@
}
/**
- * Remove any time-outs previously posted for the provided active sync.
+ * Post a delayed message that will monitor the given sync context by periodically checking how
+ * much network has been used by the uid.
*/
- private void removeSyncExpiryMessage(ActiveSyncContext activeSyncContext) {
+ private void postMonitorSyncProgressMessage(ActiveSyncContext activeSyncContext) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "removing all MESSAGE_SYNC_EXPIRED for " + activeSyncContext.toString());
+ Log.v(TAG, "posting MESSAGE_SYNC_MONITOR in " +
+ (SYNC_MONITOR_WINDOW_LENGTH_MILLIS/1000) + "s");
}
- mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext);
+
+ activeSyncContext.mBytesTransferredAtLastPoll =
+ getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid);
+ activeSyncContext.mLastPolledTimeElapsed = SystemClock.elapsedRealtime();
+ Message monitorMessage =
+ mSyncHandler.obtainMessage(
+ SyncHandler.MESSAGE_MONITOR_SYNC,
+ activeSyncContext);
+ mSyncHandler.sendMessageDelayed(monitorMessage, SYNC_MONITOR_WINDOW_LENGTH_MILLIS);
}
+ /**
+ * Monitor sync progress by calculating how many bytes it is managing to send to and fro.
+ */
+ private long getTotalBytesTransferredByUid(int uid) {
+ return (TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid));
+ }
+
+ /**
+ * Convenience class for passing parameters for a finished or cancelled sync to the handler
+ * to be processed.
+ */
class SyncHandlerMessagePayload {
public final ActiveSyncContext activeSyncContext;
public final SyncResult syncResult;
- SyncHandlerMessagePayload(ActiveSyncContext syncContext, SyncResult syncResult) {
+ SyncHandlerMessagePayload(ActiveSyncContext syncContext,
+ SyncResult syncResult) {
this.activeSyncContext = syncContext;
this.syncResult = syncResult;
}
@@ -1236,7 +1272,7 @@
* @param userId The user for which the package has become active. Can be USER_ALL if
* the device just plugged in.
*/
- void onAppNotIdle(String packageName, int userId) {
+ void onAppNotIdle(@Nullable String packageName, int userId) {
synchronized (mSyncQueue) {
// For all sync operations in sync queue, if marked as idle, compare with package name
// and unmark. And clear backoff for the operation.
@@ -1277,6 +1313,14 @@
boolean mIsLinkedToDeath = false;
String mEventName;
+ /** Total bytes transferred, counted at {@link #mLastPolledTimeElapsed} */
+ long mBytesTransferredAtLastPoll;
+ /**
+ * Last point in {@link SystemClock#elapsedRealtime()} at which we checked the # of bytes
+ * transferred to/fro by this adapter.
+ */
+ long mLastPolledTimeElapsed;
+
/**
* Create an ActiveSyncContext for an impending sync and grab the wakelock for that
* sync adapter. Since this grabs the wakelock you need to be sure to call
@@ -2048,8 +2092,16 @@
private static final int MESSAGE_SERVICE_CONNECTED = 4;
private static final int MESSAGE_SERVICE_DISCONNECTED = 5;
private static final int MESSAGE_CANCEL = 6;
- /** Posted delayed in order to expire syncs that are long-running. */
+ /**
+ * Posted delayed in order to expire syncs that are long-running.
+ * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext}
+ */
private static final int MESSAGE_SYNC_EXPIRED = 7;
+ /**
+ * Posted periodically to monitor network process for long-running syncs.
+ * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext}
+ */
+ private static final int MESSAGE_MONITOR_SYNC = 8;
public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
private Long mAlarmScheduleTime = null;
@@ -2167,28 +2219,16 @@
// to also take into account the periodic syncs.
earliestFuturePollTime = scheduleReadyPeriodicSyncs();
switch (msg.what) {
- case SyncHandler.MESSAGE_SYNC_EXPIRED:
- ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj;
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED: expiring "
- + expiredContext);
- }
- cancelActiveSync(expiredContext.mSyncOperation.target,
- expiredContext.mSyncOperation.extras);
- nextPendingSyncTime = maybeStartNextSyncH();
- break;
-
- case SyncHandler.MESSAGE_CANCEL: {
- SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj;
+ case SyncHandler.MESSAGE_CANCEL:
+ SyncStorageEngine.EndPoint endpoint = (SyncStorageEngine.EndPoint) msg.obj;
Bundle extras = msg.peekData();
if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: "
- + payload + " bundle: " + extras);
+ Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: "
+ + endpoint + " bundle: " + extras);
}
- cancelActiveSyncLocked(payload, extras);
+ cancelActiveSyncH(endpoint, extras);
nextPendingSyncTime = maybeStartNextSyncH();
break;
- }
case SyncHandler.MESSAGE_SYNC_FINISHED:
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2254,7 +2294,6 @@
// since a sync just finished check if it is time to start a new sync
nextPendingSyncTime = maybeStartNextSyncH();
}
-
break;
}
@@ -2278,6 +2317,36 @@
}
nextPendingSyncTime = maybeStartNextSyncH();
break;
+ case SyncHandler.MESSAGE_SYNC_EXPIRED:
+ ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj;
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED:" +
+ " cancelling " + expiredContext);
+ }
+ runSyncFinishedOrCanceledH(
+ null /* cancel => no result */,
+ expiredContext);
+ nextPendingSyncTime = maybeStartNextSyncH();
+ break;
+ case SyncHandler.MESSAGE_MONITOR_SYNC:
+ ActiveSyncContext monitoredSyncContext = (ActiveSyncContext) msg.obj;
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_MONITOR_SYNC: " +
+ monitoredSyncContext.mSyncOperation.target);
+ }
+
+ if (isSyncNotUsingNetworkH(monitoredSyncContext)) {
+ Log.w(TAG, String.format(
+ "Detected sync making no progress for %s. cancelling.",
+ monitoredSyncContext));
+ runSyncFinishedOrCanceledH(
+ null /* cancel => no result */, monitoredSyncContext);
+ } else {
+ // Repost message to check again.
+ postMonitorSyncProgressMessage(monitoredSyncContext);
+ }
+ break;
+
}
} finally {
manageSyncNotificationLocked();
@@ -2699,6 +2768,30 @@
return nextReadyToRunTime;
}
+ private boolean isSyncNotUsingNetworkH(ActiveSyncContext activeSyncContext) {
+ final long bytesTransferredCurrent =
+ getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid);
+ final long deltaBytesTransferred =
+ bytesTransferredCurrent - activeSyncContext.mBytesTransferredAtLastPoll;
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ // Bytes transferred
+ long remainder = deltaBytesTransferred;
+ long mb = remainder / (1024 * 1024);
+ remainder %= 1024 * 1024;
+ long kb = remainder / 1024;
+ remainder %= 1024;
+ long b = remainder;
+ Log.d(TAG, String.format(
+ "Time since last update: %ds. Delta transferred: %dMBs,%dKBs,%dBs",
+ (SystemClock.elapsedRealtime()
+ - activeSyncContext.mLastPolledTimeElapsed)/1000,
+ mb, kb, b)
+ );
+ }
+ return (deltaBytesTransferred <= SYNC_MONITOR_PROGRESS_THRESHOLD_BYTES);
+ }
+
/**
* Determine if a sync is no longer valid and should be dropped from the sync queue and its
* pending op deleted.
@@ -2849,18 +2942,22 @@
}
ActiveSyncContext activeSyncContext =
new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid);
- activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
- mActiveSyncContexts.add(activeSyncContext);
- if (!activeSyncContext.mSyncOperation.isInitialization() &&
- !activeSyncContext.mSyncOperation.isExpedited() &&
- !activeSyncContext.mSyncOperation.isManual() &&
- !activeSyncContext.mSyncOperation.isIgnoreSettings()) {
- // Post message to expire this sync if it runs for too long.
- postSyncExpiryMessage(activeSyncContext);
- }
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext);
}
+
+ activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
+ mActiveSyncContexts.add(activeSyncContext);
+ // Post message to cancel this sync if it runs for too long.
+ if (!activeSyncContext.mSyncOperation.isExpedited() &&
+ !activeSyncContext.mSyncOperation.isManual() &&
+ !activeSyncContext.mSyncOperation.isIgnoreSettings()) {
+ postSyncExpiryMessage(activeSyncContext);
+ }
+
+ // Post message to begin monitoring this sync's progress.
+ postMonitorSyncProgressMessage(activeSyncContext);
+
if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
Log.e(TAG, "Bind attempt failed - target: " + targetComponent);
closeActiveSyncContext(activeSyncContext);
@@ -2902,9 +2999,10 @@
/**
* Cancel the sync for the provided target that matches the given bundle.
- * @param info can have null fields to indicate all the active syncs for that field.
+ * @param info Can have null fields to indicate all the active syncs for that field.
+ * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint.
*/
- private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) {
+ private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) {
ArrayList<ActiveSyncContext> activeSyncs =
new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
for (ActiveSyncContext activeSyncContext : activeSyncs) {
@@ -2920,8 +3018,7 @@
false /* no config settings */)) {
continue;
}
- runSyncFinishedOrCanceledH(null /* no result since this is a cancel */,
- activeSyncContext);
+ runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
}
}
}
@@ -3034,7 +3131,13 @@
mActiveSyncContexts.remove(activeSyncContext);
mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo,
activeSyncContext.mSyncOperation.target.userId);
- removeSyncExpiryMessage(activeSyncContext);
+
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "removing all MESSAGE_MONITOR_SYNC & MESSAGE_SYNC_EXPIRED for "
+ + activeSyncContext.toString());
+ }
+ mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext);
+ mSyncHandler.removeMessages(SyncHandler.MESSAGE_MONITOR_SYNC, activeSyncContext);
}
/**
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 35fbef6..8d2687b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -231,6 +231,9 @@
// The elapsed real time when the screen on was blocked.
private long mScreenOnBlockStartRealTime;
+ // True if we told the window manager policy that the screen was off.
+ private boolean mReportedScreenOffToPolicy;
+
// Remembers whether certain kinds of brightness adjustments
// were recently applied so that we can decide how to transition.
private boolean mAppliedAutoBrightness;
@@ -764,24 +767,30 @@
} catch (RemoteException ex) {
// same process
}
-
- // Tell the window manager what's happening.
- // Temporarily block turning the screen on until the window manager is ready
- // by leaving a black surface covering the screen. This surface is essentially
- // the final state of the color fade animation.
- boolean isOn = (state != Display.STATE_OFF);
- if (wasOn && !isOn) {
- unblockScreenOn();
- mWindowManagerPolicy.screenTurnedOff();
- } else if (!wasOn && isOn) {
- if (mPowerState.getColorFadeLevel() == 0.0f) {
- blockScreenOn();
- } else {
- unblockScreenOn();
- }
- mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
- }
}
+
+ // Tell the window manager policy when the screen is turned off or on unless it's due
+ // to the proximity sensor. We temporarily block turning the screen on until the
+ // window manager is ready by leaving a black surface covering the screen.
+ // This surface is essentially the final state of the color fade animation and
+ // it is only removed once the window manager tells us that the activity has
+ // finished drawing underneath.
+ final boolean isOff = (state == Display.STATE_OFF);
+ if (isOff && !mReportedScreenOffToPolicy && !mScreenOffBecauseOfProximity) {
+ mReportedScreenOffToPolicy = true;
+ unblockScreenOn();
+ mWindowManagerPolicy.screenTurnedOff();
+ } else if (!isOff && mReportedScreenOffToPolicy) {
+ mReportedScreenOffToPolicy = false;
+ if (mPowerState.getColorFadeLevel() == 0.0f) {
+ blockScreenOn();
+ } else {
+ unblockScreenOn();
+ }
+ mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
+ }
+
+ // Return true if the screen isn't blocked.
return mPendingScreenOnUnblocker == null;
}
@@ -1086,6 +1095,7 @@
pw.println(" mAppliedLowPower=" + mAppliedLowPower);
pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
pw.println(" mPendingScreenOff=" + mPendingScreenOff);
+ pw.println(" mReportedScreenOffToPolicy=" + mReportedScreenOffToPolicy);
pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" +
mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 98fb11b..02d4f40 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -17,12 +17,7 @@
package com.android.server.job.controllers;
import android.app.usage.UsageStatsManagerInternal;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
-import android.os.BatteryManagerInternal;
import android.util.Slog;
import com.android.server.LocalServices;
@@ -38,8 +33,7 @@
* for a certain amount of time (maybe hours or days) are considered idle. When the app comes
* out of idle state, it will be allowed to run scheduled jobs.
*/
-public class AppIdleController extends StateController
- implements UsageStatsManagerInternal.AppIdleStateChangeListener {
+public class AppIdleController extends StateController {
private static final String LOG_TAG = "AppIdleController";
private static final boolean DEBUG = false;
@@ -49,14 +43,7 @@
private static volatile AppIdleController sController;
final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
private final UsageStatsManagerInternal mUsageStatsInternal;
- private final BatteryManager mBatteryManager;
- private boolean mPluggedIn;
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override public void onReceive(Context context, Intent intent) {
- onPluggedIn(mBatteryManager.isCharging());
- }
- };
+ boolean mAppIdleParoleOn;
public static AppIdleController get(JobSchedulerService service) {
synchronized (sCreationLock) {
@@ -70,17 +57,8 @@
private AppIdleController(StateChangedListener stateChangedListener, Context context) {
super(stateChangedListener, context);
mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
- mBatteryManager = context.getSystemService(BatteryManager.class);
- mPluggedIn = mBatteryManager.isCharging();
- mUsageStatsInternal.addAppIdleStateChangeListener(this);
- registerReceivers();
- }
-
- private void registerReceivers() {
- // Monitor battery charging state
- IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING);
- filter.addAction(BatteryManager.ACTION_DISCHARGING);
- mContext.registerReceiver(mReceiver, filter);
+ mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn();
+ mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
}
@Override
@@ -88,7 +66,7 @@
synchronized (mTrackedTasks) {
mTrackedTasks.add(jobStatus);
String packageName = jobStatus.job.getService().getPackageName();
- final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName,
+ final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
jobStatus.getUserId());
if (DEBUG) {
Slog.d(LOG_TAG, "Start tracking, setting idle state of "
@@ -108,7 +86,7 @@
@Override
public void dumpControllerState(PrintWriter pw) {
pw.println("AppIdle");
- pw.println("Plugged In: " + mPluggedIn);
+ pw.println("Parole On: " + mAppIdleParoleOn);
synchronized (mTrackedTasks) {
for (JobStatus task : mTrackedTasks) {
pw.print(task.job.getService().getPackageName());
@@ -119,48 +97,20 @@
}
}
- @Override
- public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
- boolean changed = false;
- synchronized (mTrackedTasks) {
- // If currently plugged in, we don't care about app idle state
- if (mPluggedIn) {
- return;
- }
- for (JobStatus task : mTrackedTasks) {
- if (task.job.getService().getPackageName().equals(packageName)
- && task.getUserId() == userId) {
- if (task.appNotIdleConstraintSatisfied.get() != !idle) {
- if (DEBUG) {
- Slog.d(LOG_TAG, "App Idle state changed, setting idle state of "
- + packageName + " to " + idle);
- }
- task.appNotIdleConstraintSatisfied.set(!idle);
- changed = true;
- }
- }
- }
- }
- if (changed) {
- mStateChangedListener.onControllerStateChanged();
- }
- }
-
- void onPluggedIn(boolean pluggedIn) {
+ void setAppIdleParoleOn(boolean isAppIdleParoleOn) {
// Flag if any app's idle state has changed
boolean changed = false;
synchronized (mTrackedTasks) {
- if (mPluggedIn == pluggedIn) {
+ if (mAppIdleParoleOn == isAppIdleParoleOn) {
return;
}
- mPluggedIn = pluggedIn;
+ mAppIdleParoleOn = isAppIdleParoleOn;
for (JobStatus task : mTrackedTasks) {
String packageName = task.job.getService().getPackageName();
- final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName,
+ final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
task.getUserId());
if (DEBUG) {
- Slog.d(LOG_TAG, "Plugged in " + pluggedIn + ", setting idle state of "
- + packageName + " to " + appIdle);
+ Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle);
}
if (task.appNotIdleConstraintSatisfied.get() == appIdle) {
task.appNotIdleConstraintSatisfied.set(!appIdle);
@@ -172,4 +122,41 @@
mStateChangedListener.onControllerStateChanged();
}
}
+
+ private class AppIdleStateChangeListener
+ extends UsageStatsManagerInternal.AppIdleStateChangeListener {
+ @Override
+ public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
+ boolean changed = false;
+ synchronized (mTrackedTasks) {
+ if (mAppIdleParoleOn) {
+ return;
+ }
+ for (JobStatus task : mTrackedTasks) {
+ if (task.job.getService().getPackageName().equals(packageName)
+ && task.getUserId() == userId) {
+ if (task.appNotIdleConstraintSatisfied.get() != !idle) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "App Idle state changed, setting idle state of "
+ + packageName + " to " + idle);
+ }
+ task.appNotIdleConstraintSatisfied.set(!idle);
+ changed = true;
+ }
+ }
+ }
+ }
+ if (changed) {
+ mStateChangedListener.onControllerStateChanged();
+ }
+ }
+
+ @Override
+ public void onParoleStateChanged(boolean isParoleOn) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "Parole on: " + isParoleOn);
+ }
+ setAppIdleParoleOn(isParoleOn);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 259ff1d..d4f3c4d 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -136,6 +136,10 @@
}
maybeSendCapabilities();
+
+ if (mGeofenceHardwareSink != null) {
+ mGeofenceHardwareSink.setVersion(getVersion());
+ }
}
private void onBatchingStatus(int status) {
@@ -152,10 +156,23 @@
}
}
+ // Returns the current version of the FLP HAL. This depends both on the version of the
+ // structure returned by the hardware layer, and whether or not we've received the
+ // capabilities callback on initialization. Assume original version until we get
+ // the new initialization callback.
+ private int getVersion() {
+ synchronized (mLocationSinkLock) {
+ if (mHaveBatchingCapabilities) {
+ return mVersion;
+ }
+ }
+ return 1;
+ }
+
private void setVersion(int version) {
mVersion = version;
if (mGeofenceHardwareSink != null) {
- mGeofenceHardwareSink.setVersion(version);
+ mGeofenceHardwareSink.setVersion(getVersion());
}
}
@@ -375,7 +392,7 @@
@Override
public void flushBatchedLocations() {
- if (mVersion >= FIRST_VERSION_WITH_FLUSH_LOCATIONS) {
+ if (getVersion() >= FIRST_VERSION_WITH_FLUSH_LOCATIONS) {
nativeFlushBatchedLocations();
} else {
Log.wtf(TAG,
@@ -405,7 +422,7 @@
@Override
public int getVersion() {
- return mVersion;
+ return FlpHardwareProvider.this.getVersion();
}
};
@@ -482,7 +499,7 @@
private GeofenceHardwareImpl getGeofenceHardwareSink() {
if (mGeofenceHardwareSink == null) {
mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext);
- mGeofenceHardwareSink.setVersion(mVersion);
+ mGeofenceHardwareSink.setVersion(getVersion());
}
return mGeofenceHardwareSink;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b0550d6..847bcb5 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -86,7 +86,6 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.app.usage.UsageStatsManagerInternal;
-import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -154,7 +153,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -182,8 +180,7 @@
* and delivers to listeners, such as {@link ConnectivityManager}, for
* enforcement.
*/
-public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
- implements AppIdleStateChangeListener {
+public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String TAG = "NetworkPolicy";
private static final boolean LOGD = false;
private static final boolean LOGV = false;
@@ -279,6 +276,7 @@
final SparseIntArray mUidPolicy = new SparseIntArray();
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
+ /** Set of states for the child firewall chains. True if the chain is active. */
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
/**
@@ -508,7 +506,7 @@
WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
- mUsageStats.addAppIdleStateChangeListener(this);
+ mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
}
@@ -2043,7 +2041,12 @@
}
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
}
- enableFirewallChain(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
+ enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
+ }
+
+ void updateRulesForAppIdleParoleLocked() {
+ boolean enableChain = !mUsageStats.isAppIdleParoleOn();
+ enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
}
/**
@@ -2187,9 +2190,9 @@
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
if (oldFirewallReject != firewallReject) {
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject);
- if (mDeviceIdleMode && !firewallReject) {
- // if we are in device idle mode, and we decide to allow this uid. we need to punch
- // a hole in the device idle chain.
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE) && !firewallReject) {
+ // if the dozable chain is on, and we decide to allow this uid. we need to punch
+ // a hole in the dozable chain.
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false);
}
}
@@ -2207,15 +2210,25 @@
}
}
- @Override
- public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
- try {
- int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
- synchronized (mRulesLock) {
- updateRulesForUidLocked(uid);
+ private class AppIdleStateChangeListener
+ extends UsageStatsManagerInternal.AppIdleStateChangeListener {
+
+ @Override
+ public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
+ try {
+ int uid = mContext.getPackageManager().getPackageUid(packageName, userId);
+ synchronized (mRulesLock) {
+ updateRulesForUidLocked(uid);
+ }
+ } catch (NameNotFoundException nnfe) {
}
- } catch (NameNotFoundException nnfe) {
- return;
+ }
+
+ @Override
+ public void onParoleStateChanged(boolean isParoleOn) {
+ synchronized (mRulesLock) {
+ updateRulesForAppIdleParoleLocked();
+ }
}
}
@@ -2381,12 +2394,13 @@
/**
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
- private void enableFirewallChain(int chain, boolean enable) {
+ private void enableFirewallChainLocked(int chain, boolean enable) {
if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
mFirewallChainStates.get(chain) == enable) {
// All is the same, nothing to do.
return;
}
+ mFirewallChainStates.put(chain, enable);
try {
mNetworkManager.setFirewallChainEnabled(chain, enable);
} catch (IllegalStateException e) {
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index fdb443e..87b4f8c 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -16,6 +16,8 @@
package com.android.server.notification;
+import com.android.internal.statusbar.NotificationVisibility;
+
public interface NotificationDelegate {
void onSetDisabled(int status);
void onClearAll(int callingUid, int callingPid, int userId);
@@ -30,6 +32,7 @@
void onPanelHidden();
void clearEffects();
void onNotificationVisibilityChanged(
- String[] newlyVisibleKeys, String[] noLongerVisibleKeys);
+ NotificationVisibility[] newlyVisibleKeys,
+ NotificationVisibility[] noLongerVisibleKeys);
void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0dcad82..4524ff8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -97,6 +97,7 @@
import android.widget.Toast;
import com.android.internal.R;
+import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -622,22 +623,24 @@
}
@Override
- public void onNotificationVisibilityChanged(
- String[] newlyVisibleKeys, String[] noLongerVisibleKeys) {
+ public void onNotificationVisibilityChanged(NotificationVisibility[] newlyVisibleKeys,
+ NotificationVisibility[] noLongerVisibleKeys) {
synchronized (mNotificationList) {
- for (String key : newlyVisibleKeys) {
- NotificationRecord r = mNotificationsByKey.get(key);
+ for (NotificationVisibility nv : newlyVisibleKeys) {
+ NotificationRecord r = mNotificationsByKey.get(nv.key);
if (r == null) continue;
- r.setVisibility(true);
+ r.setVisibility(true, nv.rank);
+ nv.recycle();
}
// Note that we might receive this event after notifications
// have already left the system, e.g. after dismissing from the
// shade. Hence not finding notifications in
// mNotificationsByKey is not an exceptional condition.
- for (String key : noLongerVisibleKeys) {
- NotificationRecord r = mNotificationsByKey.get(key);
+ for (NotificationVisibility nv : noLongerVisibleKeys) {
+ NotificationRecord r = mNotificationsByKey.get(nv.key);
if (r == null) continue;
- r.setVisibility(false);
+ r.setVisibility(false, nv.rank);
+ nv.recycle();
}
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index c4773ca..b7aea9d 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -314,13 +314,15 @@
/**
* Set the visibility of the notification.
*/
- public void setVisibility(boolean visible) {
+ public void setVisibility(boolean visible, int rank) {
final long now = System.currentTimeMillis();
mVisibleSinceMs = visible ? now : mVisibleSinceMs;
stats.onVisibilityChanged(visible);
EventLogTags.writeNotificationVisibility(getKey(), visible ? 1 : 0,
(int) (now - mCreationTimeMs),
- (int) (now - mUpdateTimeMs));
+ (int) (now - mUpdateTimeMs),
+ 0, // exposure time
+ rank);
}
/**
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 2d5c199..2f0cc0f 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -16,11 +16,13 @@
package com.android.server.notification;
+import android.app.Notification;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -57,8 +59,8 @@
private static final boolean DEBUG = false;
public static final int TEN_SECONDS = 1000 * 10;
- public static final int ONE_HOUR = 1000 * 60 * 60;
- private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : ONE_HOUR;
+ public static final int FOUR_HOURS = 1000 * 60 * 60 * 4;
+ private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : FOUR_HOURS;
// Guarded by synchronized(this).
private final Map<String, AggregatedStats> mStats = new HashMap<>();
@@ -98,6 +100,7 @@
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
for (AggregatedStats stats : aggregatedStatsArray) {
stats.numPostedByApp++;
+ stats.countApiUse(notification);
}
releaseAggregatedStatsLocked(aggregatedStatsArray);
if (ENABLE_SQLITE_LOG) {
@@ -113,6 +116,7 @@
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
for (AggregatedStats stats : aggregatedStatsArray) {
stats.numUpdatedByApp++;
+ stats.countApiUse(notification);
}
releaseAggregatedStatsLocked(aggregatedStatsArray);
}
@@ -246,6 +250,7 @@
private final Context mContext;
public final String key;
+ private AggregatedStats mPrevious;
// ---- Updated as the respective events occur.
public int numPostedByApp;
@@ -256,14 +261,103 @@
public int numWithStaredPeople;
public int numWithValidPeople;
public int numBlocked;
-
- private AggregatedStats mPrevious;
+ public int numWithActions;
+ public int numPrivate;
+ public int numSecret;
+ public int numPriorityMax;
+ public int numPriorityHigh;
+ public int numPriorityLow;
+ public int numPriorityMin;
+ public int numWithBigText;
+ public int numWithBigPicture;
+ public int numForegroundService;
+ public int numOngoing;
+ public int numAutoCancel;
+ public int numWithLargeIcon;
+ public int numWithInbox;
+ public int numWithMediaSession;
+ public int numWithTitle;
+ public int numWithText;
+ public int numWithSubText;
+ public int numWithInfoText;
+ public int numInterrupt;
public AggregatedStats(Context context, String key) {
this.key = key;
mContext = context;
}
+ public void countApiUse(NotificationRecord record) {
+ final Notification n = record.getNotification();
+ if (n.actions != null) {
+ numWithActions++;
+ }
+
+ if ((n.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+ numForegroundService++;
+ }
+
+ if ((n.flags & Notification.FLAG_ONGOING_EVENT) != 0) {
+ numOngoing++;
+ }
+
+ if ((n.flags & Notification.FLAG_AUTO_CANCEL) != 0) {
+ numAutoCancel++;
+ }
+
+ if ((n.defaults & Notification.DEFAULT_SOUND) != 0 ||
+ (n.defaults & Notification.DEFAULT_VIBRATE) != 0 ||
+ n.sound != null || n.vibrate != null) {
+ numInterrupt++;
+ }
+
+ switch (n.visibility) {
+ case Notification.VISIBILITY_PRIVATE:
+ numPrivate++;
+ break;
+ case Notification.VISIBILITY_SECRET:
+ numSecret++;
+ break;
+ }
+
+ switch (n.priority) {
+ case Notification.PRIORITY_MAX:
+ numPriorityMax++;
+ break;
+ case Notification.PRIORITY_HIGH:
+ numPriorityHigh++;
+ break;
+ case Notification.PRIORITY_LOW:
+ numPriorityLow++;
+ break;
+ case Notification.PRIORITY_MIN:
+ numPriorityMin++;
+ break;
+ }
+
+ for (String Key : n.extras.keySet()) {
+ if (Notification.EXTRA_BIG_TEXT.equals(key)) {
+ numWithBigText++;
+ } else if (Notification.EXTRA_PICTURE.equals(key)) {
+ numWithBigPicture++;
+ } else if (Notification.EXTRA_LARGE_ICON.equals(key)) {
+ numWithLargeIcon++;
+ } else if (Notification.EXTRA_TEXT_LINES.equals(key)) {
+ numWithInbox++;
+ } else if (Notification.EXTRA_MEDIA_SESSION.equals(key)) {
+ numWithMediaSession++;
+ } else if (Notification.EXTRA_TITLE.equals(key)) {
+ numWithTitle++;
+ } else if (Notification.EXTRA_TEXT.equals(key)) {
+ numWithText++;
+ } else if (Notification.EXTRA_SUB_TEXT.equals(key)) {
+ numWithSubText++;
+ } else if (Notification.EXTRA_INFO_TEXT.equals(key)) {
+ numWithInfoText++;
+ }
+ }
+ }
+
public void emit() {
if (mPrevious == null) {
mPrevious = new AggregatedStats(null, key);
@@ -277,6 +371,26 @@
maybeCount("people_cache_hit", (numPeopleCacheHit - mPrevious.numPeopleCacheHit));
maybeCount("people_cache_miss", (numPeopleCacheMiss - mPrevious.numPeopleCacheMiss));
maybeCount("note_blocked", (numBlocked - mPrevious.numBlocked));
+ maybeCount("note_with_actions", (numWithActions - mPrevious.numWithActions));
+ maybeCount("note_private", (numPrivate - mPrevious.numPrivate));
+ maybeCount("note_secret", (numSecret - mPrevious.numSecret));
+ maybeCount("note_prio_max", (numPriorityMax - mPrevious.numPriorityMax));
+ maybeCount("note_prio_high", (numPriorityHigh - mPrevious.numPriorityHigh));
+ maybeCount("note_prio_low", (numPriorityLow - mPrevious.numPriorityLow));
+ maybeCount("note_prio_min", (numPriorityMin - mPrevious.numPriorityMin));
+ maybeCount("note_interupt", (numInterrupt - mPrevious.numInterrupt));
+ maybeCount("note_big_text", (numWithBigText - mPrevious.numWithBigText));
+ maybeCount("note_big_pic", (numWithBigPicture - mPrevious.numWithBigPicture));
+ maybeCount("note_fg", (numForegroundService - mPrevious.numForegroundService));
+ maybeCount("note_ongoing", (numOngoing - mPrevious.numOngoing));
+ maybeCount("note_auto", (numAutoCancel - mPrevious.numAutoCancel));
+ maybeCount("note_large_icon", (numWithLargeIcon - mPrevious.numWithLargeIcon));
+ maybeCount("note_inbox", (numWithInbox - mPrevious.numWithInbox));
+ maybeCount("note_media", (numWithMediaSession - mPrevious.numWithMediaSession));
+ maybeCount("note_title", (numWithTitle - mPrevious.numWithTitle));
+ maybeCount("note_text", (numWithText - mPrevious.numWithText));
+ maybeCount("note_sub_text", (numWithSubText - mPrevious.numWithSubText));
+ maybeCount("note_info_text", (numWithInfoText - mPrevious.numWithInfoText));
mPrevious.numPostedByApp = numPostedByApp;
mPrevious.numUpdatedByApp = numUpdatedByApp;
@@ -286,6 +400,26 @@
mPrevious.numWithStaredPeople = numWithStaredPeople;
mPrevious.numWithValidPeople = numWithValidPeople;
mPrevious.numBlocked = numBlocked;
+ mPrevious.numWithActions = numWithActions;
+ mPrevious.numPrivate = numPrivate;
+ mPrevious.numSecret = numSecret;
+ mPrevious.numPriorityMax = numPriorityMax;
+ mPrevious.numPriorityHigh = numPriorityHigh;
+ mPrevious.numPriorityLow = numPriorityLow;
+ mPrevious.numPriorityMin = numPriorityMin;
+ mPrevious.numInterrupt = numInterrupt;
+ mPrevious.numWithBigText = numWithBigText;
+ mPrevious.numWithBigPicture = numWithBigPicture;
+ mPrevious.numForegroundService = numForegroundService;
+ mPrevious.numOngoing = numOngoing;
+ mPrevious.numAutoCancel = numAutoCancel;
+ mPrevious.numWithLargeIcon = numWithLargeIcon;
+ mPrevious.numWithInbox = numWithInbox;
+ mPrevious.numWithMediaSession = numWithMediaSession;
+ mPrevious.numWithTitle = numWithTitle;
+ mPrevious.numWithText = numWithText;
+ mPrevious.numWithSubText = numWithSubText;
+ mPrevious.numWithInfoText = numWithInfoText;
}
void maybeCount(String name, int value) {
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index fe3103b..3ea384c 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -45,7 +45,7 @@
* have phone related permission by default.
*/
final class DefaultPermissionGrantPolicy {
- private static final String TAG = "DefaultPermissionGrantPolicy";
+ private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
private static final boolean DEBUG = false;
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
@@ -106,7 +106,7 @@
private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
static {
-// STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
@@ -133,6 +133,7 @@
private PackagesProvider mImePackagesProvider;
private PackagesProvider mLocationPackagesProvider;
private PackagesProvider mVoiceInteractionPackagesProvider;
+ private PackagesProvider mCarrierAppPackagesProvider;
public DefaultPermissionGrantPolicy(PackageManagerService service) {
mService = service;
@@ -150,6 +151,10 @@
mVoiceInteractionPackagesProvider = provider;
}
+ public void setCarrierAppPackagesProviderLPw(PackagesProvider provider) {
+ mCarrierAppPackagesProvider = provider;
+ }
+
public void grantDefaultPermissions(int userId) {
grantPermissionsToSysComponentsAndPrivApps(userId);
grantDefaultSystemHandlerPermissions(userId);
@@ -193,11 +198,13 @@
final PackagesProvider imePackagesProvider;
final PackagesProvider locationPackagesProvider;
final PackagesProvider voiceInteractionPackagesProvider;
+ final PackagesProvider carrierAppPackagesProvider;
synchronized (mService.mPackages) {
imePackagesProvider = mImePackagesProvider;
locationPackagesProvider = mLocationPackagesProvider;
voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
+ carrierAppPackagesProvider = mCarrierAppPackagesProvider;
}
String[] imePackageNames = (imePackagesProvider != null)
@@ -206,6 +213,8 @@
? voiceInteractionPackagesProvider.getPackages(userId) : null;
String[] locationPackageNames = (locationPackagesProvider != null)
? locationPackagesProvider.getPackages(userId) : null;
+ String[] carrierAppPackageNames = (carrierAppPackagesProvider != null)
+ ? carrierAppPackagesProvider.getPackages(userId) : null;
synchronized (mService.mPackages) {
// Installers
@@ -382,6 +391,18 @@
}
}
}
+
+ // Carrier apps
+ if (carrierAppPackageNames != null) {
+ for (String packageName : carrierAppPackageNames) {
+ PackageParser.Package carrierPackage = getSystemPackageLPr(packageName);
+ if (carrierPackage != null
+ && doesPackageSupportRuntimePermissions(carrierPackage)) {
+ grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
+ }
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
index c09d6ae..c6e7911 100644
--- a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
+++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
@@ -19,7 +19,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.util.ArraySet;
-import android.util.Log;
+import android.util.Slog;
import java.util.ArrayList;
@@ -113,7 +113,7 @@
setState(state);
return true;
}
- Log.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" +
+ Slog.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" +
code + " as required verifierUid is:" + mRequiredVerifierUid);
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 95cb11d..dbf0f17 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -100,6 +100,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.IPackagesProvider;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
@@ -212,6 +213,7 @@
import com.android.server.storage.DeviceStorageMonitorInternal;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
@@ -253,14 +255,14 @@
/**
* Keep track of all those .apks everywhere.
- *
+ *
* This is very central to the platform's security; please run the unit
* tests whenever making modifications here:
- *
+ *
mmm frameworks/base/tests/AndroidTests
adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
- *
+ *
* {@hide}
*/
public class PackageManagerService extends IPackageManager.Stub {
@@ -308,6 +310,7 @@
static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
static final int SCAN_REQUIRE_KNOWN = 1<<12;
static final int SCAN_MOVE = 1<<13;
+ static final int SCAN_INITIAL = 1<<14;
static final int REMOVE_CHATTY = 1<<16;
@@ -508,7 +511,7 @@
// Packages whose data we have transfered into another package, thus
// should no longer exist.
final ArraySet<String> mTransferedPackages = new ArraySet<String>();
-
+
// Broadcast actions that are only available to the system.
final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
@@ -556,6 +559,22 @@
final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
new DefaultPermissionGrantPolicy(this);
+ private static class IFVerificationParams {
+ PackageParser.Package pkg;
+ boolean replacing;
+ int userId;
+ int verifierUid;
+
+ public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
+ int _userId, int _verifierUid) {
+ pkg = _pkg;
+ replacing = _replacing;
+ userId = _userId;
+ replacing = _replacing;
+ verifierUid = _verifierUid;
+ }
+ }
+
private interface IntentFilterVerifier<T extends IntentFilter> {
boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
T filter, String packageName);
@@ -629,7 +648,7 @@
UserHandle user = new UserHandle(userId);
mContext.sendBroadcastAsUser(verificationIntent, user);
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
- "Sending IntenFilter verification broadcast");
+ "Sending IntentFilter verification broadcast");
}
public void receiveVerificationResponse(int verificationId) {
@@ -639,6 +658,10 @@
ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
final int count = filters.size();
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Received verification response " + verificationId
+ + " for " + count + " filters, verified=" + verified);
+ }
for (int n=0; n<count; n++) {
PackageParser.ActivityIntentInfo filter = filters.get(n);
filter.setVerified(verified);
@@ -713,30 +736,27 @@
}
@Override
- public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
+ public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
ActivityIntentInfo filter, String packageName) {
- if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
- filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
- if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
- "IntentFilter does not contain HTTP nor HTTPS data scheme");
+ if (!hasValidDomains(filter)) {
return false;
}
IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
if (ivs == null) {
- ivs = createDomainVerificationState(verifierId, userId, verificationId,
+ ivs = createDomainVerificationState(verifierUid, userId, verificationId,
packageName);
}
- if (!hasValidDomains(filter)) {
- return false;
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter);
}
ivs.addFilter(filter);
return true;
}
- private IntentFilterVerificationState createDomainVerificationState(int verifierId,
+ private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
int userId, int verificationId, String packageName) {
IntentFilterVerificationState ivs = new IntentFilterVerificationState(
- verifierId, userId, packageName);
+ verifierUid, userId, packageName);
ivs.setPendingState();
synchronized (mPackages) {
mIntentFilterVerificationStates.append(verificationId, ivs);
@@ -871,7 +891,7 @@
public void onServiceDisconnected(ComponentName name) {
if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
}
- };
+ }
// Recordkeeping of restore-after-install operations that are currently in flight
// between the Package Manager and the Backup Manager
@@ -883,12 +903,15 @@
args = _a;
res = _r;
}
- };
+ }
+
final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
- // backup/restore of preferred activity state
+ // XML tags for backup/restore of various bits of state
private static final String TAG_PREFERRED_BACKUP = "pa";
+ private static final String TAG_DEFAULT_APPS = "da";
+ private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
private final String mRequiredVerifierPackage;
@@ -1071,7 +1094,7 @@
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
}
-
+
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
@@ -1109,13 +1132,18 @@
mContainerService = (IMediaContainerService) msg.obj;
}
if (mContainerService == null) {
- // Something seriously wrong. Bail out
- Slog.e(TAG, "Cannot bind to media container service");
- for (HandlerParams params : mPendingInstalls) {
- // Indicate service bind error
- params.serviceError();
+ if (!mBound) {
+ // Something seriously wrong since we are not bound and we are not
+ // waiting for connection. Bail out.
+ Slog.e(TAG, "Cannot bind to media container service");
+ for (HandlerParams params : mPendingInstalls) {
+ // Indicate service bind error
+ params.serviceError();
+ }
+ mPendingInstalls.clear();
+ } else {
+ Slog.w(TAG, "Waiting to connect to media container service");
}
- mPendingInstalls.clear();
} else if (mPendingInstalls.size() > 0) {
HandlerParams params = mPendingInstalls.get(0);
if (params != null) {
@@ -1501,11 +1529,9 @@
break;
}
case START_INTENT_FILTER_VERIFICATIONS: {
- int userId = msg.arg1;
- int verifierUid = msg.arg2;
- PackageParser.Package pkg = (PackageParser.Package)msg.obj;
-
- verifyIntentFiltersIfNeeded(userId, verifierUid, pkg);
+ IFVerificationParams params = (IFVerificationParams) msg.obj;
+ verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
+ params.replacing, params.pkg);
break;
}
case INTENT_FILTER_VERIFIED: {
@@ -1815,7 +1841,7 @@
// Set flag to monitor and not change apk file paths when
// scanning install directories.
- final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
+ final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
@@ -2351,8 +2377,7 @@
final String packageName = getDefaultBrowserPackageName(myUserId);
PackageInfo info = getPackageInfo(packageName, 0, myUserId);
if (info == null) {
- Slog.w(TAG, "Clearing default Browser as its package is no more installed: " +
- packageName);
+ Slog.w(TAG, "Default browser no longer installed: " + packageName);
setDefaultBrowserPackageName(null, myUserId);
}
}
@@ -2479,7 +2504,7 @@
}
return out;
}
-
+
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
String[] out = new String[names.length];
@@ -2549,7 +2574,7 @@
pi.protectionLevel = bp.protectionLevel;
return pi;
}
-
+
@Override
public PermissionInfo getPermissionInfo(String name, int flags) {
// reader
@@ -3029,7 +3054,7 @@
}
return s1.equals(s2);
}
-
+
static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
if (pi1.icon != pi2.icon) return false;
if (pi1.logo != pi2.logo) return false;
@@ -3331,11 +3356,8 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"updatePermissionFlags");
- // Only the system can change policy and system fixed flags.
+ // Only the system can change system fixed flags.
if (getCallingUid() != Process.SYSTEM_UID) {
- flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
- flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
-
flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
}
@@ -3364,18 +3386,63 @@
return;
}
+ boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
+
if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
// Install and runtime permissions are stored in different places,
// so figure out what permission changed and persist the change.
if (permissionsState.getInstallPermissionState(name) != null) {
scheduleWriteSettingsLocked();
- } else if (permissionsState.getRuntimePermissionState(name, userId) != null) {
+ } else if (permissionsState.getRuntimePermissionState(name, userId) != null
+ || hadState) {
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
}
}
}
+ /**
+ * Update the permission flags for all packages and runtime permissions of a user in order
+ * to allow device or profile owner to remove POLICY_FIXED.
+ */
+ @Override
+ public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return;
+ }
+
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+ "updatePermissionFlagsForAllApps");
+
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+ "updatePermissionFlagsForAllApps");
+
+ // Only the system can change system fixed flags.
+ if (getCallingUid() != Process.SYSTEM_UID) {
+ flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ }
+
+ synchronized (mPackages) {
+ boolean changed = false;
+ final int packageCount = mPackages.size();
+ for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
+ final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
+ SettingBase sb = (SettingBase) pkg.mExtras;
+ if (sb == null) {
+ continue;
+ }
+ PermissionsState permissionsState = sb.getPermissionsState();
+ changed |= permissionsState.updatePermissionFlagsForAllPermissions(
+ userId, flagMask, flagValues);
+ }
+ if (changed) {
+ mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+ }
+ }
+ }
+
@Override
public boolean shouldShowRequestPermissionRationale(String permissionName,
String packageName, int userId) {
@@ -4112,9 +4179,26 @@
if (matches.get(i).getTargetUserId() == targetUserId) return true;
}
}
+ if (hasWebURI(intent)) {
+ // cross-profile app linking works only towards the parent.
+ final UserInfo parent = getProfileParent(sourceUserId);
+ synchronized(mPackages) {
+ return getCrossProfileDomainPreferredLpr(intent, resolvedType, 0, sourceUserId,
+ parent.id) != null;
+ }
+ }
return false;
}
+ private UserInfo getProfileParent(int userId) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return sUserManager.getProfileParent(userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
String resolvedType, int userId) {
CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
@@ -4132,7 +4216,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -4155,11 +4239,11 @@
List<CrossProfileIntentFilter> matchingFilters =
getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
// Check for results that need to skip the current profile.
- ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
+ ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
resolvedType, flags, userId);
- if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
+ if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
- result.add(resolveInfo);
+ result.add(xpResolveInfo);
return filterIfNotPrimaryUser(result, userId);
}
@@ -4168,15 +4252,36 @@
intent, resolvedType, flags, userId);
// Check for cross profile results.
- resolveInfo = queryCrossProfileIntents(
+ xpResolveInfo = queryCrossProfileIntents(
matchingFilters, intent, resolvedType, flags, userId);
- if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
- result.add(resolveInfo);
+ if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
+ result.add(xpResolveInfo);
Collections.sort(result, mResolvePrioritySorter);
}
result = filterIfNotPrimaryUser(result, userId);
- if (result.size() > 1 && hasWebURI(intent)) {
- return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result);
+ if (hasWebURI(intent)) {
+ CrossProfileDomainInfo xpDomainInfo = null;
+ final UserInfo parent = getProfileParent(userId);
+ if (parent != null) {
+ xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
+ flags, userId, parent.id);
+ }
+ if (xpDomainInfo != null) {
+ if (xpResolveInfo != null) {
+ // If we didn't remove it, the cross-profile ResolveInfo would be twice
+ // in the result.
+ result.remove(xpResolveInfo);
+ }
+ if (result.size() == 0) {
+ result.add(xpDomainInfo.resolveInfo);
+ return result;
+ }
+ } else if (result.size() <= 1) {
+ return result;
+ }
+ result = filterCandidatesWithDomainPreferredActivitiesLPr(flags, result,
+ xpDomainInfo);
+ Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
@@ -4191,6 +4296,67 @@
}
}
+ private static class CrossProfileDomainInfo {
+ /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
+ ResolveInfo resolveInfo;
+ /* Best domain verification status of the activities found in the other profile */
+ int bestDomainVerificationStatus;
+ }
+
+ private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
+ String resolvedType, int flags, int sourceUserId, int parentUserId) {
+ if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_APP_LINKING,
+ sourceUserId)) {
+ return null;
+ }
+ List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
+ resolvedType, flags, parentUserId);
+
+ if (resultTargetUser == null || resultTargetUser.isEmpty()) {
+ return null;
+ }
+ CrossProfileDomainInfo result = null;
+ int size = resultTargetUser.size();
+ for (int i = 0; i < size; i++) {
+ ResolveInfo riTargetUser = resultTargetUser.get(i);
+ // Intent filter verification is only for filters that specify a host. So don't return
+ // those that handle all web uris.
+ if (riTargetUser.handleAllWebDataURI) {
+ continue;
+ }
+ String packageName = riTargetUser.activityInfo.packageName;
+ PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
+ continue;
+ }
+ int status = getDomainVerificationStatusLPr(ps, parentUserId);
+ if (result == null) {
+ result = new CrossProfileDomainInfo();
+ result.resolveInfo =
+ createForwardingResolveInfo(null, sourceUserId, parentUserId);
+ result.bestDomainVerificationStatus = status;
+ } else {
+ result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
+ result.bestDomainVerificationStatus);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Verification statuses are ordered from the worse to the best, except for
+ * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
+ */
+ private int bestDomainVerificationStatus(int status1, int status2) {
+ if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
+ return status2;
+ }
+ if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
+ return status1;
+ }
+ return (int) MathUtils.max(status1, status2);
+ }
+
private boolean isUserEnabled(int userId) {
long callingId = Binder.clearCallingIdentity();
try {
@@ -4230,8 +4396,8 @@
return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
}
- private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
- int flags, List<ResolveInfo> candidates) {
+ private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(
+ int flags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo) {
if (DEBUG_PREFERRED) {
Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
candidates.size());
@@ -4271,12 +4437,23 @@
}
}
}
- // First try to add the "always" if there is any
+ // First try to add the "always" resolution for the current user if there is any
if (alwaysList.size() > 0) {
result.addAll(alwaysList);
+ // if there is an "always" for the parent user, add it.
+ } else if (xpDomainInfo != null && xpDomainInfo.bestDomainVerificationStatus
+ == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
+ result.add(xpDomainInfo.resolveInfo);
} else {
// Add all undefined Apps as we want them to appear in the Disambiguation dialog.
result.addAll(undefinedList);
+ if (xpDomainInfo != null && (
+ xpDomainInfo.bestDomainVerificationStatus
+ == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
+ || xpDomainInfo.bestDomainVerificationStatus
+ == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) {
+ result.add(xpDomainInfo.resolveInfo);
+ }
// Also add Browsers (all of them or only the default one)
if ((flags & MATCH_ALL) != 0) {
result.addAll(matchAllList);
@@ -4594,7 +4771,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -4645,7 +4822,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -6072,7 +6249,7 @@
+ "): packages=" + suid.packages);
}
}
-
+
// Check if we are renaming from an original package name.
PackageSetting origPackage = null;
String realName = null;
@@ -6092,7 +6269,7 @@
// it is not already done.
pkg.setPackageName(renamed);
}
-
+
} else {
for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
if ((origPackage = mSettings.peekPackageLPr(
@@ -6122,7 +6299,7 @@
}
}
}
-
+
if (mTransferedPackages.contains(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName
+ " was transferred to another, but its .apk remains");
@@ -6147,24 +6324,24 @@
// looking up the package under its new name, so getPackageLP
// can take care of fiddling things correctly.
pkg.setPackageName(origPackage.name);
-
+
// File a report about this.
String msg = "New package " + pkgSetting.realName
+ " renamed to replace old package " + pkgSetting.name;
reportSettingsProblem(Log.WARN, msg);
-
+
// Make a note of it.
mTransferedPackages.add(origPackage.name);
-
+
// No longer need to retain this.
pkgSetting.origPackage = null;
}
-
+
if (realName != null) {
// Make a note of it.
mTransferedPackages.add(pkg.packageName);
}
-
+
if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
@@ -6280,7 +6457,7 @@
}
final String pkgName = pkg.packageName;
-
+
final long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
pkg.applicationInfo.processName = fixProcessName(
@@ -8200,7 +8377,7 @@
PackageParser.ActivityIntentInfo info) {
return packageName.equals(info.activity.owner.packageName);
}
-
+
@Override
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
int match, int userId) {
@@ -8423,7 +8600,7 @@
PackageParser.ServiceIntentInfo info) {
return packageName.equals(info.service.owner.packageName);
}
-
+
@Override
protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
int match, int userId) {
@@ -8946,6 +9123,7 @@
String installerPackageName, int installerUid, UserHandle user) {
final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
params.referrerUri, installerUid, null);
+ verifParams.setInstallerUid(installerUid);
final OriginInfo origin;
if (stagedDir != null) {
@@ -11150,7 +11328,7 @@
private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
// Can't rotate keys during boot or if sharedUser.
- if (oldPs == null || (scanFlags&SCAN_BOOTING) != 0 || oldPs.sharedUser != null
+ if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
|| !oldPs.keySetData.isUsingUpgradeKeySets()) {
return false;
}
@@ -11534,6 +11712,10 @@
|| (args.volumeUuid != null));
boolean replace = false;
int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
+ if (args.move != null) {
+ // moving a complete application; perfom an initial scan on the new install location
+ scanFlags |= SCAN_INITIAL;
+ }
// Result object to be returned
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
@@ -11747,7 +11929,7 @@
return;
}
- startIntentFilterVerifications(args.user.getIdentifier(), pkg);
+ startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
if (replace) {
replacePackageLI(pkg, parseFlags, scanFlags, args.user,
@@ -11764,7 +11946,8 @@
}
}
- private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) {
+ private void startIntentFilterVerifications(int userId, boolean replacing,
+ PackageParser.Package pkg) {
if (mIntentFilterVerifierComponent == null) {
Slog.w(TAG, "No IntentFilter verification will not be done as "
+ "there is no IntentFilterVerifier available!");
@@ -11777,14 +11960,11 @@
mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
- msg.obj = pkg;
- msg.arg1 = userId;
- msg.arg2 = verifierUid;
-
+ msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
mHandler.sendMessage(msg);
}
- private void verifyIntentFiltersIfNeeded(int userId, int verifierUid,
+ private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
PackageParser.Package pkg) {
int size = pkg.activities.size();
if (size == 0) {
@@ -11804,13 +11984,26 @@
+ " if any IntentFilter from the " + size
+ " Activities needs verification ...");
- final int verificationId = mIntentFilterVerificationToken++;
int count = 0;
final String packageName = pkg.packageName;
- boolean needToVerify = false;
synchronized (mPackages) {
+ // If this is a new install and we see that we've already run verification for this
+ // package, we have nothing to do: it means the state was restored from backup.
+ if (!replacing) {
+ IntentFilterVerificationInfo ivi =
+ mSettings.getIntentFilterVerificationLPr(packageName);
+ if (ivi != null) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Package " + packageName+ " already verified: status="
+ + ivi.getStatusString());
+ }
+ return;
+ }
+ }
+
// If any filters need to be verified, then all need to be.
+ boolean needToVerify = false;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
@@ -11822,7 +12015,9 @@
}
}
}
+
if (needToVerify) {
+ final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
boolean needsFilterVerification = filter.hasWebDataURI();
@@ -13262,9 +13457,45 @@
}
/**
+ * Common machinery for picking apart a restored XML blob and passing
+ * it to a caller-supplied functor to be applied to the running system.
+ */
+ private void restoreFromXml(XmlPullParser parser, int userId,
+ String expectedStartTag, BlobXmlRestorer functor)
+ throws IOException, XmlPullParserException {
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ }
+ if (type != XmlPullParser.START_TAG) {
+ // oops didn't find a start tag?!
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Didn't find start tag during restore");
+ }
+ return;
+ }
+
+ // this is supposed to be TAG_PREFERRED_BACKUP
+ if (!expectedStartTag.equals(parser.getName())) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Found unexpected tag " + parser.getName());
+ }
+ return;
+ }
+
+ // skip interfering stuff, then we're aligned with the backing implementation
+ while ((type = parser.next()) == XmlPullParser.TEXT) { }
+ functor.apply(parser, userId);
+ }
+
+ private interface BlobXmlRestorer {
+ public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
+ }
+
+ /**
* Non-Binder method, support for the backup/restore mechanism: write the
- * full set of preferred activities in its canonical XML format. Returns true
- * on success; false otherwise.
+ * full set of preferred activities in its canonical XML format. Returns the
+ * XML output as a byte array, or null if there is none.
*/
@Override
public byte[] getPreferredActivityBackup(int userId) {
@@ -13305,32 +13536,134 @@
try {
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
-
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
+ restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readPreferredActivitiesLPw(parser, userId);
+ }
+ }
+ } );
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
}
- if (type != XmlPullParser.START_TAG) {
- // oops didn't find a start tag?!
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Didn't find start tag during restore");
- }
- return;
- }
+ }
+ }
- // this is supposed to be TAG_PREFERRED_BACKUP
- if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) {
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Found unexpected tag " + parser.getName());
- }
- return;
- }
+ /**
+ * Non-Binder method, support for the backup/restore mechanism: write the
+ * default browser (etc) settings in its canonical XML format. Returns the default
+ * browser XML representation as a byte array, or null if there is none.
+ */
+ @Override
+ public byte[] getDefaultAppsBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getDefaultAppsBackup()");
+ }
- // skip interfering stuff, then we're aligned with the backing implementation
- while ((type = parser.next()) == XmlPullParser.TEXT) { }
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ try {
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_DEFAULT_APPS);
+
synchronized (mPackages) {
- mSettings.readPreferredActivitiesLPw(parser, userId);
+ mSettings.writeDefaultAppsLPr(serializer, userId);
}
+
+ serializer.endTag(null, TAG_DEFAULT_APPS);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Unable to write default apps for backup", e);
+ }
+ return null;
+ }
+
+ return dataStream.toByteArray();
+ }
+
+ @Override
+ public void restoreDefaultApps(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restoreDefaultApps()");
+ }
+
+ try {
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+ restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readDefaultAppsLPw(parser, userId);
+ }
+ }
+ } );
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public byte[] getIntentFilterVerificationBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
+ }
+
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ try {
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
+
+ synchronized (mPackages) {
+ mSettings.writeAllDomainVerificationsLPr(serializer, userId);
+ }
+
+ serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Unable to write default apps for backup", e);
+ }
+ return null;
+ }
+
+ return dataStream.toByteArray();
+ }
+
+ @Override
+ public void restoreIntentFilterVerification(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restorePreferredActivities()");
+ }
+
+ try {
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+ restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readAllDomainVerificationsLPr(parser, userId);
+ mSettings.writeLPr();
+ }
+ }
+ } );
} catch (Exception e) {
if (DEBUG_BACKUP) {
Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
@@ -13827,7 +14160,7 @@
boolean checkin = false;
String packageName = null;
-
+
int opti = 0;
while (opti < args.length) {
String opt = args[opti];
@@ -14679,7 +15012,7 @@
for (PackageSetting ps : packages) {
final PackageParser.Package pkg;
try {
- pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null);
+ pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
loaded.add(pkg.applicationInfo);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
@@ -15473,4 +15806,55 @@
}
}
}
+
+ @Override
+ public void grantDefaultPermissions(final int userId) {
+ enforceSystemOrPhoneCaller("grantDefaultPermissions");
+ long token = Binder.clearCallingIdentity();
+ try {
+ // We cannot grant the default permissions with a lock held as
+ // we query providers from other components for default handlers
+ // such as enabled IMEs, etc.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void setCarrierAppPackagesProvider(final IPackagesProvider provider) {
+ enforceSystemOrPhoneCaller("setCarrierAppPackagesProvider");
+ long token = Binder.clearCallingIdentity();
+ try {
+ PackageManagerInternal.PackagesProvider wrapper =
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ try {
+ return provider.getPackages(userId);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+ };
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setCarrierAppPackagesProviderLPw(wrapper);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private static void enforceSystemOrPhoneCaller(String tag) {
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+ throw new SecurityException(
+ "Cannot call " + tag + " from UID " + callingUid);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index ad662be..04beafd 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -344,6 +344,22 @@
return permissionData.updateFlags(userId, flagMask, flagValues);
}
+ public boolean updatePermissionFlagsForAllPermissions(
+ int userId, int flagMask, int flagValues) {
+ enforceValidUserId(userId);
+
+ if (mPermissions == null) {
+ return false;
+ }
+ boolean changed = false;
+ final int permissionCount = mPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ PermissionData permissionData = mPermissions.valueAt(i);
+ changed |= permissionData.updateFlags(userId, flagMask, flagValues);
+ }
+ return changed;
+ }
+
/**
* Compute the Linux gids for a given device user from the permissions
* granted to this user. Note that these are computed to avoid additional
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6415343..169f6de 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -174,6 +174,8 @@
"crossProfile-intent-filters";
public static final String TAG_DOMAIN_VERIFICATION = "domain-verification";
public static final String TAG_DEFAULT_APPS= "default-apps";
+ public static final String TAG_ALL_INTENT_FILTER_VERIFICATION =
+ "all-intent-filter-verifications";
public static final String TAG_DEFAULT_BROWSER= "default-browser";
private static final String ATTR_NAME = "name";
@@ -206,10 +208,15 @@
final ArrayMap<String, PackageSetting> mPackages =
new ArrayMap<String, PackageSetting>();
+
// List of replaced system applications
private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
new ArrayMap<String, PackageSetting>();
+ // Set of restored intent-filter verification states
+ private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
+ new ArrayMap<String, IntentFilterVerificationInfo>();
+
private static int mFirstAvailableUid = 0;
// TODO: store SDK versions and fingerprint for each volume UUID
@@ -753,7 +760,8 @@
}
// Utility method that adds a PackageSetting to mPackages and
- // completes updating the shared user attributes
+ // completes updating the shared user attributes and any restored
+ // app link verification state
private void addPackageSettingLPw(PackageSetting p, String name,
SharedUserSetting sharedUser) {
mPackages.put(name, p);
@@ -776,6 +784,14 @@
p.sharedUser = sharedUser;
p.appId = sharedUser.userId;
}
+ IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name);
+ if (ivi != null) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Applying restored IVI for " + name + " : " + ivi.getStatusString());
+ }
+ mRestoredIntentFilterVerifications.remove(name);
+ p.setIntentFilterVerificationInfo(ivi);
+ }
}
/*
@@ -1259,13 +1275,13 @@
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
- String tagName = parser.getName();
+ final String tagName = parser.getName();
if (tagName.equals(TAG_ITEM)) {
CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
} else {
String msg = "Unknown element under " + TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
- parser.getName();
+ tagName;
PackageManagerService.reportSettingsProblem(Log.WARN, msg);
XmlUtils.skipCurrentTag(parser);
}
@@ -1279,7 +1295,31 @@
Log.d(TAG, "Read domain verification for package:" + ivi.getPackageName());
}
- private void readDefaultAppsLPw(XmlPullParser parser, int userId)
+ private void readRestoredIntentFilterVerifications(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ final String tagName = parser.getName();
+ if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
+ IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Restored IVI for " + ivi.getPackageName()
+ + " status=" + ivi.getStatusString());
+ }
+ mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi);
+ } else {
+ Slog.w(TAG, "Unknown element: " + tagName);
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
+ void readDefaultAppsLPw(XmlPullParser parser, int userId)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
@@ -1563,6 +1603,62 @@
}
}
+ // Specifically for backup/restore
+ void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
+ final int N = mPackages.size();
+ for (int i = 0; i < N; i++) {
+ PackageSetting ps = mPackages.valueAt(i);
+ IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
+ if (ivi != null) {
+ writeDomainVerificationsLPr(serializer, ivi);
+ }
+ }
+ serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
+ }
+
+ // Specifically for backup/restore
+ void readAllDomainVerificationsLPr(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ mRestoredIntentFilterVerifications.clear();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
+ IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
+ final String pkgName = ivi.getPackageName();
+ final PackageSetting ps = mPackages.get(pkgName);
+ if (ps != null) {
+ // known/existing package; update in place
+ ps.setIntentFilterVerificationInfo(ivi);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Restored IVI for existing app " + pkgName
+ + " status=" + ivi.getStatusString());
+ }
+ } else {
+ mRestoredIntentFilterVerifications.put(pkgName, ivi);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Restored IVI for pending app " + pkgName
+ + " status=" + ivi.getStatusString());
+ }
+ }
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Unknown element under <all-intent-filter-verification>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(null, TAG_DEFAULT_APPS);
@@ -2012,6 +2108,23 @@
}
}
+ final int numIVIs = mRestoredIntentFilterVerifications.size();
+ if (numIVIs > 0) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
+ }
+ serializer.startTag(null, "restored-ivi");
+ for (int i = 0; i < numIVIs; i++) {
+ IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
+ writeDomainVerificationsLPr(serializer, ivi);
+ }
+ serializer.endTag(null, "restored-ivi");
+ } else {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, " no restored IVI entries to write");
+ }
+ }
+
mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
serializer.endTag(null, "packages");
@@ -2441,6 +2554,8 @@
if (nname != null && oname != null) {
mRenamedPackages.put(nname, oname);
}
+ } else if (tagName.equals("restored-ivi")) {
+ readRestoredIntentFilterVerifications(parser);
} else if (tagName.equals("last-platform-version")) {
mInternalSdkPlatform = mExternalSdkPlatform = 0;
try {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4082ff3..8a8d2a6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -972,6 +972,7 @@
writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT);
+ writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_APP_LINKING);
serializer.endTag(null, TAG_RESTRICTIONS);
}
@@ -1103,6 +1104,7 @@
readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER);
readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT);
+ readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_APP_LINKING);
}
private void readBoolean(XmlPullParser parser, Bundle restrictions,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index bd545df..93e1f18 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3927,7 +3927,8 @@
// A window that has requested to fill the entire screen just
// gets everything, period.
if (attrs.type == TYPE_STATUS_BAR_PANEL
- || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
+ || attrs.type == TYPE_STATUS_BAR_SUB_PANEL
+ || attrs.type == TYPE_VOLUME_OVERLAY) {
pf.left = df.left = of.left = cf.left = hasNavBar
? mDockLeft : mUnrestrictedScreenLeft;
pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
@@ -4042,9 +4043,9 @@
"): normal window");
// Otherwise, a normal window must be placed inside the content
// of all screen decorations.
- if (attrs.type == TYPE_STATUS_BAR_PANEL) {
- // Status bar panels are the only windows who can go on top of
- // the status bar. They are protected by the STATUS_BAR_SERVICE
+ if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_VOLUME_OVERLAY) {
+ // Status bar panels and the volume dialog are the only windows who can go on
+ // top of the status bar. They are protected by the STATUS_BAR_SERVICE
// permission, so they have the same privileges as the status
// bar itself.
pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft;
@@ -4053,8 +4054,7 @@
+ mRestrictedScreenWidth;
pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop
+ mRestrictedScreenHeight;
- } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT
- || attrs.type == TYPE_VOLUME_OVERLAY) {
+ } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) {
// These dialogs are stable to interim decor changes.
pf.left = df.left = of.left = cf.left = mStableLeft;
pf.top = df.top = of.top = cf.top = mStableTop;
@@ -5381,10 +5381,16 @@
}
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) {
- if (!wakeInTheaterMode && isTheaterModeEnabled()) {
+ final boolean theaterModeEnabled = isTheaterModeEnabled();
+ if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
}
+ if (theaterModeEnabled) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.THEATER_MODE_ON, 0);
+ }
+
mPowerManager.wakeUp(wakeTime);
return true;
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 5a391f4..d21c6d2 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -95,6 +95,9 @@
private final Intent mScreenOffIntent;
private final Intent mScreenBrightnessBoostIntent;
+ // True if the device should suspend when the screen is off due to proximity.
+ private final boolean mSuspendWhenScreenOffDueToProximityConfig;
+
// The current interactive state. This is set as soon as an interactive state
// transition begins so as to capture the reason that it happened. At some point
// this state will propagate to the pending state then eventually to the
@@ -143,6 +146,9 @@
mScreenBrightnessBoostIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+ mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
+
// Initialize interactive state for battery stats.
try {
mBatteryStats.noteInteractive(true);
@@ -161,22 +167,24 @@
+ ", workSource=" + workSource);
}
- try {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
- && ownerUid == Process.SYSTEM_UID;
- if (workSource != null) {
- mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
- monitorType, unimportantForLogging);
- } else {
- mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
- monitorType, unimportantForLogging);
- // XXX need to deal with disabled operations.
- mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ if (monitorType >= 0) {
+ try {
+ final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
+ && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
+ if (workSource != null) {
+ mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
+ historyTag, monitorType, unimportantForLogging);
+ } else {
+ mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+ monitorType, unimportantForLogging);
+ // XXX need to deal with disabled operations.
+ mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
+ AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ }
+ } catch (RemoteException ex) {
+ // Ignore
}
- } catch (RemoteException ex) {
- // Ignore
}
}
@@ -188,17 +196,19 @@
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
- if (workSource != null && newWorkSource != null) {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
- boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
- && newOwnerUid == Process.SYSTEM_UID;
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+ if (workSource != null && newWorkSource != null
+ && monitorType >= 0 && newMonitorType >= 0) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ "\", packageName=" + newPackageName
+ ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+ ", workSource=" + newWorkSource);
}
+
+ final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
+ && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
try {
mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
@@ -225,28 +235,50 @@
+ ", workSource=" + workSource);
}
- try {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- if (workSource != null) {
- mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, historyTag,
- monitorType);
- } else {
- mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, historyTag, monitorType);
- mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ if (monitorType >= 0) {
+ try {
+ if (workSource != null) {
+ mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
+ historyTag, monitorType);
+ } else {
+ mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
+ historyTag, monitorType);
+ mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
+ AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ }
+ } catch (RemoteException ex) {
+ // Ignore
}
- } catch (RemoteException ex) {
- // Ignore
}
}
- private static int getBatteryStatsWakeLockMonitorType(int flags) {
+ private int getBatteryStatsWakeLockMonitorType(int flags) {
switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
case PowerManager.PARTIAL_WAKE_LOCK:
- case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
return BatteryStats.WAKE_TYPE_PARTIAL;
- default:
+
+ case PowerManager.SCREEN_DIM_WAKE_LOCK:
+ case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
return BatteryStats.WAKE_TYPE_FULL;
+
+ case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+ if (mSuspendWhenScreenOffDueToProximityConfig) {
+ return -1;
+ }
+ return BatteryStats.WAKE_TYPE_PARTIAL;
+
+ case PowerManager.DRAW_WAKE_LOCK:
+ return BatteryStats.WAKE_TYPE_DRAW;
+
+ case PowerManager.DOZE_WAKE_LOCK:
+ // Doze wake locks are an internal implementation detail of the
+ // communication between dream manager service and power manager
+ // service. They have no additive battery impact.
+ return -1;
+
+ default:
+ return -1;
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3af97db..51bb36f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -970,6 +970,7 @@
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
case PowerManager.FULL_WAKE_LOCK:
case PowerManager.DOZE_WAKE_LOCK:
+ case PowerManager.DRAW_WAKE_LOCK:
return true;
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index a754379..7640837 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -29,6 +29,7 @@
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.server.LocalServices;
@@ -660,7 +661,8 @@
@Override
public void onNotificationVisibilityChanged(
- String[] newlyVisibleKeys, String[] noLongerVisibleKeys) throws RemoteException {
+ NotificationVisibility[] newlyVisibleKeys, NotificationVisibility[] noLongerVisibleKeys)
+ throws RemoteException {
enforceStatusBarService();
long identity = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ace5997..b285b66 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2671,6 +2671,16 @@
synchronized(mWindowMap) {
mScreenCaptureDisabled.put(userId, disabled);
+ // Update secure surface for all windows belonging to this user.
+ for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
+ win.mWinAnimator.setSecureLocked(disabled);
+ }
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f1331e9..d818519 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -658,6 +658,11 @@
}
@Override
+ public void setSecure(boolean isSecure) {
+ super.setSecure(isSecure);
+ }
+
+ @Override
public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
@@ -1663,6 +1668,22 @@
}
}
+ void setSecureLocked(boolean isSecure) {
+ if (mSurfaceControl == null) {
+ return;
+ }
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
+ SurfaceControl.openTransaction();
+ try {
+ if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isSecure=" + isSecure,
+ null);
+ mSurfaceControl.setSecure(isSecure);
+ } finally {
+ SurfaceControl.closeTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
+ }
+ }
+
// This must be called while inside a transaction.
boolean performShowLocked() {
if (mWin.isHiddenFromUserLocked()) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3b62b61..e44a7ab87 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -246,6 +246,7 @@
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
+ GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
}
// Keyguard features that when set of a profile will affect the profiles
@@ -3231,15 +3232,21 @@
}
final UserHandle caller = Binder.getCallingUserHandle();
- final ComponentName profileOwner = getProfileOwner(caller.getIdentifier());
-
- if (profileOwner == null) {
+ // If there is a profile owner, redirect to that; otherwise query the device owner.
+ ComponentName aliasChooser = getProfileOwner(caller.getIdentifier());
+ if (aliasChooser == null && caller.isOwner()) {
+ ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdmin();
+ if (deviceOwnerAdmin != null) {
+ aliasChooser = deviceOwnerAdmin.info.getComponent();
+ }
+ }
+ if (aliasChooser == null) {
sendPrivateKeyAliasResponse(null, response);
return;
}
Intent intent = new Intent(DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS);
- intent.setComponent(profileOwner);
+ intent.setComponent(aliasChooser);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, uid);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI, uri);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias);
@@ -4210,11 +4217,15 @@
long ident = Binder.clearCallingIdentity();
try {
clearUserRestrictions(new UserHandle(UserHandle.USER_OWNER));
+ AppGlobals.getPackageManager().updatePermissionFlagsForAllApps(
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED,
+ 0, UserHandle.USER_OWNER);
if (mDeviceOwner != null) {
mDeviceOwner.clearDeviceOwner();
mDeviceOwner.writeOwnerFile();
updateDeviceOwnerLocked();
}
+ } catch (RemoteException re) {
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4381,10 +4392,14 @@
long ident = Binder.clearCallingIdentity();
try {
clearUserRestrictions(callingUser);
+ AppGlobals.getPackageManager().updatePermissionFlagsForAllApps(
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED,
+ 0, callingUser.getIdentifier());
if (mDeviceOwner != null) {
mDeviceOwner.removeProfileOwner(userId);
mDeviceOwner.writeOwnerFile();
}
+ } catch (RemoteException re) {
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6383,21 +6398,27 @@
getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long ident = Binder.clearCallingIdentity();
try {
- PackageManager packageManager = mContext.getPackageManager();
+ final ApplicationInfo ai = AppGlobals.getPackageManager()
+ .getApplicationInfo(packageName, 0, user.getIdentifier());
+ final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
+ if (targetSdkVersion < android.os.Build.VERSION_CODES.MNC) {
+ return false;
+ }
+ final PackageManager packageManager = mContext.getPackageManager();
switch (grantState) {
case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
+ packageManager.grantRuntimePermission(packageName, permission, user);
packageManager.updatePermissionFlags(permission, packageName,
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
- packageManager.grantRuntimePermission(packageName, permission, user);
} break;
case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: {
+ packageManager.revokeRuntimePermission(packageName,
+ permission, user);
packageManager.updatePermissionFlags(permission, packageName,
PackageManager.FLAG_PERMISSION_POLICY_FIXED,
PackageManager.FLAG_PERMISSION_POLICY_FIXED, user);
- packageManager.revokeRuntimePermission(packageName,
- permission, user);
} break;
case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: {
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 712db09..fb8a5bb 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -34,6 +34,7 @@
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
@@ -792,6 +793,30 @@
handlerThread.quit();
}
+ @LargeTest
+ public void testNoMutableNetworkRequests() throws Exception {
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
+ NetworkRequest.Builder builder = new NetworkRequest.Builder();
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ try {
+ mCm.requestNetwork(builder.build(), new NetworkCallback());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ mCm.requestNetwork(builder.build(), pendingIntent);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ builder = new NetworkRequest.Builder();
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
+ try {
+ mCm.requestNetwork(builder.build(), new NetworkCallback());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ mCm.requestNetwork(builder.build(), pendingIntent);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
// @Override
// public void tearDown() throws Exception {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3b7ed91..c49a5f9 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -35,8 +35,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SyncAdapterType;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
@@ -74,7 +72,6 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.DeviceIdleController;
import com.android.server.SystemService;
import java.io.BufferedReader;
@@ -122,6 +119,7 @@
static final int MSG_CHECK_PAROLE_TIMEOUT = 6;
static final int MSG_PAROLE_END_TIMEOUT = 7;
static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
+ static final int MSG_PAROLE_STATE_CHANGED = 9;
private final Object mLock = new Object();
Handler mHandler;
@@ -138,6 +136,7 @@
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
+ boolean mAppIdleEnabled;
boolean mAppIdleParoled;
private boolean mScreenOn;
private long mLastAppIdleParoledTime;
@@ -175,10 +174,15 @@
getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, userActions,
null, null);
- IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
- deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
- deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
- getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
+ mAppIdleEnabled = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_enableAutoPowerModes);
+ if (mAppIdleEnabled) {
+ IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
+ deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
+ deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+ getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
+ }
+
synchronized (mLock) {
cleanUpRemovedUsersLocked();
}
@@ -186,7 +190,6 @@
mRealTimeSnapshot = SystemClock.elapsedRealtime();
mSystemTimeSnapshot = System.currentTimeMillis();
-
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
@@ -311,7 +314,7 @@
mLastAppIdleParoledTime = checkAndGetTimeLocked();
postNextParoleTimeout();
}
- postCheckIdleStates(UserHandle.USER_ALL);
+ postParoleStateChanged();
}
}
}
@@ -336,12 +339,22 @@
mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, mAppIdleParoleDurationMillis);
}
+ private void postParoleStateChanged() {
+ if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED");
+ mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED);
+ mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED);
+ }
+
void postCheckIdleStates(int userId) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
}
/** Check all running users' or specified user's apps to see if they enter an idle state. */
void checkIdleStates(int checkUserId) {
+ if (!mAppIdleEnabled) {
+ return;
+ }
+
final int[] userIds;
try {
if (checkUserId == UserHandle.USER_ALL) {
@@ -750,6 +763,13 @@
}
}
+ boolean isAppIdleFilteredOrParoled(String packageName, int userId, long timeNow) {
+ if (mAppIdleParoled) {
+ return false;
+ }
+ return isAppIdleFiltered(packageName, userId, timeNow);
+ }
+
boolean isAppIdleFiltered(String packageName, int userId, long timeNow) {
final UserUsageStatsService userService;
final long screenOnTime;
@@ -772,12 +792,9 @@
private boolean isAppIdleFiltered(String packageName, int userId,
UserUsageStatsService userService, long timeNow, long screenOnTime) {
if (packageName == null) return false;
- synchronized (mLock) {
- // Temporary exemption, probably due to device charging or occasional allowance to
- // be allowed to sync, etc.
- if (mAppIdleParoled) {
- return false;
- }
+ // If not enabled at all, of course nobody is ever idle.
+ if (!mAppIdleEnabled) {
+ return false;
}
if (packageName.equals("android")) return false;
try {
@@ -836,6 +853,12 @@
}
}
+ void informParoleStateChanged() {
+ for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
+ listener.onParoleStateChanged(mAppIdleParoled);
+ }
+ }
+
private static boolean validRange(long currentTime, long beginTime, long endTime) {
return beginTime <= currentTime && beginTime < endTime;
}
@@ -900,6 +923,19 @@
pw.print(" mAppIdleParoleDurationMillis=");
TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw);
pw.println();
+
+ pw.println();
+ pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
+ pw.print(" mAppIdleParoled="); pw.print(mAppIdleParoled);
+ pw.print(" mScreenOn="); pw.println(mScreenOn);
+ pw.print("mLastAppIdleParoledTime=");
+ TimeUtils.formatDuration(mLastAppIdleParoledTime, pw);
+ pw.println();
+ pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
+ pw.println();
+ pw.print("mScreenOnSystemTimeSnapshot=");
+ TimeUtils.formatDuration(mScreenOnSystemTimeSnapshot, pw);
+ pw.println();
}
}
@@ -952,6 +988,11 @@
args.recycle();
break;
+ case MSG_PAROLE_STATE_CHANGED:
+ if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled);
+ informParoleStateChanged();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -1103,7 +1144,7 @@
}
final long token = Binder.clearCallingIdentity();
try {
- return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
+ return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, -1);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1228,6 +1269,11 @@
}
@Override
+ public boolean isAppIdleParoleOn() {
+ return mAppIdleParoled;
+ }
+
+ @Override
public void prepareShutdown() {
// This method *WILL* do IO work, but we must block until it is finished or else
// we might not shutdown cleanly. This is ok to do with the 'am' lock held, because
@@ -1238,6 +1284,7 @@
@Override
public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) {
UsageStatsService.this.addListener(listener);
+ listener.onParoleStateChanged(isAppIdleParoleOn());
}
@Override
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 91566f8..6055211 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1067,6 +1067,9 @@
@SystemApi
@Deprecated
public final AudioState getAudioState() {
+ if (mCallAudioState == null) {
+ return null;
+ }
return new AudioState(mCallAudioState);
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f77d268..cec11cf 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -33,9 +33,11 @@
import android.util.Log;
import com.android.internal.telecom.ITelecomService;
+import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
+import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyProperties;
@@ -942,10 +944,17 @@
/** {@hide} */
@SystemApi
public int getCurrentPhoneType(int subId) {
- int phoneId = SubscriptionManager.getPhoneId(subId);
+ int phoneId;
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ // if we don't have any sims, we don't have subscriptions, but we
+ // still may want to know what type of phone we've got.
+ phoneId = 0;
+ } else {
+ phoneId = SubscriptionManager.getPhoneId(subId);
+ }
try{
ITelephony telephony = getITelephony();
- if (telephony != null) {
+ if (telephony != null && subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return telephony.getActivePhoneTypeForSubscriber(subId);
} else {
// This can happen when the ITelephony interface is not up yet.
@@ -3433,6 +3442,55 @@
}
/**
+ * Perform a radio scan and return the list of avialble networks.
+ *
+ * The return value is a list of the OperatorInfo of the networks found. Note that this
+ * scan can take a long time (sometimes minutes) to happen.
+ *
+ * <p>
+ * Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+ *
+ * @hide
+ */
+ public CellNetworkScanResult getCellNetworkScanResults(int subId) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ return telephony.getCellNetworkScanResults(subId);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getCellNetworkScanResults RemoteException", ex);
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "getCellNetworkScanResults NPE", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Ask the radio to connect to the input network and change selection mode to manual.
+ *
+ * <p>
+ * Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+ *
+ * @hide
+ */
+ public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ return telephony.setNetworkSelectionModeManual(subId, operator);
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "setNetworkSelectionModeManual RemoteException", ex);
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "setNetworkSelectionModeManual NPE", ex);
+ }
+ return false;
+ }
+
+ /**
* Set the preferred network type.
* Used for device configuration by some CDMA operators.
* <p>
diff --git a/telephony/java/com/android/internal/telephony/CellNetworkScanResult.aidl b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.aidl
new file mode 100644
index 0000000..7917a81
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.aidl
@@ -0,0 +1,19 @@
+/*
+** 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.
+*/
+
+package com.android.internal.telephony;
+
+parcelable CellNetworkScanResult;
diff --git a/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
new file mode 100644
index 0000000..c708c14
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
@@ -0,0 +1,125 @@
+/*
+** 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.
+*/
+
+package com.android.internal.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Response for querying available cellular networks.
+ *
+ * @hide
+ */
+public class CellNetworkScanResult implements Parcelable {
+
+ /**
+ * Possible status values.
+ */
+ public static final int STATUS_SUCCESS = 1;
+ public static final int STATUS_RADIO_NOT_AVAILABLE = 2;
+ public static final int STATUS_RADIO_GENERIC_FAILURE = 3;
+ public static final int STATUS_UNKNOWN_ERROR = 4;
+
+ private final int mStatus;
+ private final List<OperatorInfo> mOperators;
+
+ /**
+ * Constructor.
+ *
+ * @hide
+ */
+ public CellNetworkScanResult(int status, List<OperatorInfo> operators) {
+ mStatus = status;
+ mOperators = operators;
+ }
+
+ /**
+ * Construct a CellNetworkScanResult from a given parcel.
+ */
+ private CellNetworkScanResult(Parcel in) {
+ mStatus = in.readInt();
+ int len = in.readInt();
+ if (len > 0) {
+ mOperators = new ArrayList();
+ for (int i = 0; i < len; ++i) {
+ mOperators.add(OperatorInfo.CREATOR.createFromParcel(in));
+ }
+ } else {
+ mOperators = null;
+ }
+ }
+
+ /**
+ * @return the status of the command.
+ */
+ public int getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * @return the operators.
+ */
+ public List<OperatorInfo> getOperators() {
+ return mOperators;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mStatus);
+ if (mOperators != null && mOperators.size() > 0) {
+ for (OperatorInfo network : mOperators) {
+ network.writeToParcel(out, flags);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("CellNetworkScanResult: {");
+ sb.append(" status:").append(mStatus);
+ if (mOperators != null) {
+ for (OperatorInfo network : mOperators) {
+ sb.append(" network:").append(network);
+ }
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ public static final Parcelable.Creator<CellNetworkScanResult> CREATOR
+ = new Parcelable.Creator<CellNetworkScanResult>() {
+
+ @Override
+ public CellNetworkScanResult createFromParcel(Parcel in) {
+ return new CellNetworkScanResult(in);
+ }
+
+ public CellNetworkScanResult[] newArray(int size) {
+ return new CellNetworkScanResult[size];
+ }
+ };
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 44754ab..7dc71ed 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -24,6 +24,8 @@
import android.telephony.NeighboringCellInfo;
import android.telephony.RadioAccessFamily;
import android.telephony.ModemActivityInfo;
+import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.OperatorInfo;
import java.util.List;
@@ -679,6 +681,23 @@
void setNetworkSelectionModeAutomatic(int subId);
/**
+ * Perform a radio scan and return the list of avialble networks.
+ *
+ * @param subId the id of the subscription.
+ * @return CellNetworkScanResult containing status of scan and networks.
+ */
+ CellNetworkScanResult getCellNetworkScanResults(int subId);
+
+ /**
+ * Ask the radio to connect to the input network and change selection mode to manual.
+ *
+ * @param subId the id of the subscription.
+ * @param operatorInfo the operator to attach to.
+ * @return true if the request suceeded.
+ */
+ boolean setNetworkSelectionModeManual(int subId, in OperatorInfo operator);
+
+ /**
* Set the preferred network type.
* Used for device configuration by some CDMA operators.
*
@@ -917,7 +936,6 @@
* @return {@code true} if the device supports hearing aid compatibility.
*/
boolean isHearingAidCompatibilitySupported();
-
/**
* Get IMS Registration Status
*/
diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java
new file mode 100644
index 0000000..a29d7c1
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.internal.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+public class OperatorInfo implements Parcelable {
+ public enum State {
+ UNKNOWN,
+ AVAILABLE,
+ CURRENT,
+ FORBIDDEN;
+ }
+
+ private String mOperatorAlphaLong;
+ private String mOperatorAlphaShort;
+ private String mOperatorNumeric;
+
+ private State mState = State.UNKNOWN;
+
+
+ public String
+ getOperatorAlphaLong() {
+ return mOperatorAlphaLong;
+ }
+
+ public String
+ getOperatorAlphaShort() {
+ return mOperatorAlphaShort;
+ }
+
+ public String
+ getOperatorNumeric() {
+ return mOperatorNumeric;
+ }
+
+ public State
+ getState() {
+ return mState;
+ }
+
+ OperatorInfo(String operatorAlphaLong,
+ String operatorAlphaShort,
+ String operatorNumeric,
+ State state) {
+
+ mOperatorAlphaLong = operatorAlphaLong;
+ mOperatorAlphaShort = operatorAlphaShort;
+ mOperatorNumeric = operatorNumeric;
+
+ mState = state;
+ }
+
+
+ public OperatorInfo(String operatorAlphaLong,
+ String operatorAlphaShort,
+ String operatorNumeric,
+ String stateString) {
+ this (operatorAlphaLong, operatorAlphaShort,
+ operatorNumeric, rilStateToState(stateString));
+ }
+
+ public OperatorInfo(String operatorAlphaLong,
+ String operatorAlphaShort,
+ String operatorNumeric) {
+ this(operatorAlphaLong, operatorAlphaShort, operatorNumeric, State.UNKNOWN);
+ }
+
+ /**
+ * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
+ */
+ private static State rilStateToState(String s) {
+ if (s.equals("unknown")) {
+ return State.UNKNOWN;
+ } else if (s.equals("available")) {
+ return State.AVAILABLE;
+ } else if (s.equals("current")) {
+ return State.CURRENT;
+ } else if (s.equals("forbidden")) {
+ return State.FORBIDDEN;
+ } else {
+ throw new RuntimeException(
+ "RIL impl error: Invalid network state '" + s + "'");
+ }
+ }
+
+
+ @Override
+ public String toString() {
+ return "OperatorInfo " + mOperatorAlphaLong
+ + "/" + mOperatorAlphaShort
+ + "/" + mOperatorNumeric
+ + "/" + mState;
+ }
+
+ /**
+ * Parcelable interface implemented below.
+ * This is a simple effort to make OperatorInfo parcelable rather than
+ * trying to make the conventional containing object (AsyncResult),
+ * implement parcelable. This functionality is needed for the
+ * NetworkQueryService to fix 1128695.
+ */
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Implement the Parcelable interface.
+ * Method to serialize a OperatorInfo object.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mOperatorAlphaLong);
+ dest.writeString(mOperatorAlphaShort);
+ dest.writeString(mOperatorNumeric);
+ dest.writeSerializable(mState);
+ }
+
+ /**
+ * Implement the Parcelable interface
+ * Method to deserialize a OperatorInfo object, or an array thereof.
+ */
+ public static final Creator<OperatorInfo> CREATOR =
+ new Creator<OperatorInfo>() {
+ @Override
+ public OperatorInfo createFromParcel(Parcel in) {
+ OperatorInfo opInfo = new OperatorInfo(
+ in.readString(), /*operatorAlphaLong*/
+ in.readString(), /*operatorAlphaShort*/
+ in.readString(), /*operatorNumeric*/
+ (State) in.readSerializable()); /*state*/
+ return opInfo;
+ }
+
+ @Override
+ public OperatorInfo[] newArray(int size) {
+ return new OperatorInfo[size];
+ }
+ };
+}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index 8a72341..439ace8 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -17,7 +17,7 @@
package com.android.test.voiceinteraction;
import android.annotation.Nullable;
-import android.app.AssistStructure;
+import android.app.assist.AssistStructure;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 3090a11..90a781c 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -18,8 +18,8 @@
import android.app.ActivityManager;
import android.app.VoiceInteractor;
-import android.app.AssistContent;
-import android.app.AssistStructure;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -123,34 +123,8 @@
}
public void onHandleAssist(Bundle assistBundle) {
- boolean hasStructure = false;
- if (assistBundle != null) {
- Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- mAssistStructure = AssistStructure.getAssistStructure(assistContext);
- if (mAssistStructure != null) {
- if (mAssistVisualizer != null) {
- mAssistVisualizer.setAssistStructure(mAssistStructure);
- hasStructure = true;
- }
- }
- AssistContent content = AssistContent.getAssistContent(assistContext);
- if (content != null) {
- Log.i(TAG, "Assist intent: " + content.getIntent());
- Log.i(TAG, "Assist clipdata: " + content.getClipData());
- }
- }
- Uri referrer = assistBundle.getParcelable(Intent.EXTRA_REFERRER);
- if (referrer != null) {
- Log.i(TAG, "Referrer: " + referrer);
- }
- }
- if (!hasStructure && mAssistVisualizer != null) {
- mAssistVisualizer.clearAssistData();
- }
}
- /*
@Override
public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
mAssistStructure = structure;
@@ -158,13 +132,22 @@
if (mAssistVisualizer != null) {
mAssistVisualizer.setAssistStructure(mAssistStructure);
}
+ } else {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.clearAssistData();
+ }
}
if (content != null) {
Log.i(TAG, "Assist intent: " + content.getIntent());
Log.i(TAG, "Assist clipdata: " + content.getClipData());
}
+ if (data != null) {
+ Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER);
+ if (referrer != null) {
+ Log.i(TAG, "Referrer: " + referrer);
+ }
+ }
}
- */
@Override
public void onHandleScreenshot(Bitmap screenshot) {
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index c038414..943c647 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -16,6 +16,7 @@
package com.android.test.voiceinteraction;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.VoiceInteractor;
import android.content.ComponentName;
@@ -111,38 +112,10 @@
@Override
public void onClick(View v) {
if (v == mAbortButton) {
- VoiceInteractor.AbortVoiceRequest req = new VoiceInteractor.AbortVoiceRequest(
- new VoiceInteractor.Prompt("Dammit, we suck :("), null) {
- @Override
- public void onCancel() {
- Log.i(TAG, "Canceled!");
- mLog.append("Canceled abort\n");
- }
-
- @Override
- public void onAbortResult(Bundle result) {
- Log.i(TAG, "Abort result: result=" + result);
- mLog.append("Abort: result=" + result + "\n");
- getActivity().finish();
- }
- };
+ VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice();
mInteractor.submitRequest(req, REQUEST_ABORT);
} else if (v == mCompleteButton) {
- VoiceInteractor.CompleteVoiceRequest req = new VoiceInteractor.CompleteVoiceRequest(
- new VoiceInteractor.Prompt("Woohoo, completed!"), null) {
- @Override
- public void onCancel() {
- Log.i(TAG, "Canceled!");
- mLog.append("Canceled complete\n");
- }
-
- @Override
- public void onCompleteResult(Bundle result) {
- Log.i(TAG, "Complete result: result=" + result);
- mLog.append("Complete: result=" + result + "\n");
- getActivity().finish();
- }
- };
+ VoiceInteractor.CompleteVoiceRequest req = new TestCompleteVoice();
mInteractor.submitRequest(req, REQUEST_COMPLETE);
} else if (v == mPickButton) {
VoiceInteractor.PickOptionRequest.Option[] options =
@@ -152,36 +125,7 @@
options[2] = new VoiceInteractor.PickOptionRequest.Option("Three");
options[3] = new VoiceInteractor.PickOptionRequest.Option("Four");
options[4] = new VoiceInteractor.PickOptionRequest.Option("Five");
- VoiceInteractor.PickOptionRequest req = new VoiceInteractor.PickOptionRequest(
- new VoiceInteractor.Prompt("Need to pick something"), options, null) {
- @Override
- public void onCancel() {
- Log.i(TAG, "Canceled!");
- mLog.append("Canceled pick\n");
- }
-
- @Override
- public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
- Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections
- + " result=" + result);
- StringBuilder sb = new StringBuilder();
- if (finished) {
- sb.append("Pick final result: ");
- } else {
- sb.append("Pick intermediate result: ");
- }
- for (int i=0; i<selections.length; i++) {
- if (i >= 1) {
- sb.append(", ");
- }
- sb.append(selections[i].getLabel());
- }
- mLog.append(sb.toString());
- if (finished) {
- getActivity().finish();
- }
- }
- };
+ VoiceInteractor.PickOptionRequest req = new TestPickOption(options);
mInteractor.submitRequest(req, REQUEST_PICK);
} else if (v == mJumpOutButton) {
Log.i(TAG, "Jump out");
@@ -200,4 +144,66 @@
public void onDestroy() {
super.onDestroy();
}
+
+ static class TestAbortVoice extends VoiceInteractor.AbortVoiceRequest {
+ public TestAbortVoice() {
+ super(new VoiceInteractor.Prompt("Dammit, we suck :("), null);
+ }
+ @Override public void onCancel() {
+ Log.i(TAG, "Canceled!");
+ ((TestInteractionActivity)getActivity()).mLog.append("Canceled abort\n");
+ }
+ @Override public void onAbortResult(Bundle result) {
+ Log.i(TAG, "Abort result: result=" + result);
+ ((TestInteractionActivity)getActivity()).mLog.append("Abort: result=" + result + "\n");
+ getActivity().finish();
+ }
+ }
+
+ static class TestCompleteVoice extends VoiceInteractor.CompleteVoiceRequest {
+ public TestCompleteVoice() {
+ super(new VoiceInteractor.Prompt("Woohoo, completed!"), null);
+ }
+ @Override public void onCancel() {
+ Log.i(TAG, "Canceled!");
+ ((TestInteractionActivity)getActivity()).mLog.append("Canceled complete\n");
+ }
+ @Override public void onCompleteResult(Bundle result) {
+ Log.i(TAG, "Complete result: result=" + result);
+ ((TestInteractionActivity)getActivity()).mLog.append("Complete: result="
+ + result + "\n");
+ getActivity().finish();
+ }
+ }
+
+ static class TestPickOption extends VoiceInteractor.PickOptionRequest {
+ public TestPickOption(Option[] options) {
+ super(new VoiceInteractor.Prompt("Need to pick something"), options, null);
+ }
+ @Override public void onCancel() {
+ Log.i(TAG, "Canceled!");
+ ((TestInteractionActivity)getActivity()).mLog.append("Canceled pick\n");
+ }
+ @Override
+ public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+ Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections
+ + " result=" + result);
+ StringBuilder sb = new StringBuilder();
+ if (finished) {
+ sb.append("Pick final result: ");
+ } else {
+ sb.append("Pick intermediate result: ");
+ }
+ for (int i=0; i<selections.length; i++) {
+ if (i >= 1) {
+ sb.append(", ");
+ }
+ sb.append(selections[i].getLabel());
+ }
+ ((TestInteractionActivity)getActivity()).mLog.append(sb.toString());
+ if (finished) {
+ getActivity().finish();
+ }
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 5dc70bd..fc6a3de 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
/**
* Describes information about a detected access point. In addition
@@ -80,27 +81,30 @@
public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
/**
- * AP Channel bandwidth
+ * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
+ * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}
+ * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}.
*/
public int channelWidth;
/**
* Not used if the AP bandwidth is 20 MHz
- * If the AP use 40, 80 or 160 MHz, this is the center frequency
- * if the AP use 80 + 80 MHz, this is the center frequency of the first segment
+ * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz)
+ * if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz)
*/
public int centerFreq0;
/**
* Only used if the AP bandwidth is 80 + 80 MHz
- * if the AP use 80 + 80 MHz, this is the center frequency of the second segment
+ * if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz)
*/
public int centerFreq1;
/**
- * Whether the AP support 802.11mc Responder
+ * @deprecated use is80211mcResponder() instead
+ * @hide
*/
- public boolean is80211McRTTResponder;
+ public boolean is80211McRTTResponder;
/**
* timestamp in microseconds (since boot) when
@@ -123,7 +127,7 @@
/**
* @hide
* Update RSSI of the scan result
- * @param previousRSSI
+ * @param previousRssi
* @param previousSeen
* @param maxAge
*/
@@ -206,26 +210,56 @@
public int distanceCm;
/**
- * The standard deviation of the distance to the AP, if available.
+ * The standard deviation of the distance to the access point, if available.
* Else {@link UNSPECIFIED}.
* {@hide}
*/
public int distanceSdCm;
- /**
- * Indicates if the scan result represents a passpoint AP
- */
- public boolean passpointNetwork;
+ public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001;
+ public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002;
/**
- * Indicates if venue name
+ * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
*/
- public String venueName;
+ public long flags;
/**
- * Indicates operator name
+ * sets a flag in {@link #flags} field
+ * @param flag flag to set
+ * @hide
*/
- public String operatorFriendlyName;
+ public void setFlag(long flag) {
+ flags |= flag;
+ }
+
+ /**
+ * clears a flag in {@link #flags} field
+ * @param flag flag to set
+ * @hide
+ */
+ public void clearFlag(long flag) {
+ flags &= ~flag;
+ }
+
+ public boolean is80211mcResponder() {
+ return (flags & FLAG_80211mc_RESPONDER) != 0;
+ }
+
+ public boolean isPasspointNetwork() {
+ return (flags & FLAG_PASSPOINT_NETWORK) != 0;
+ }
+
+ /**
+ * Indicates venue name (such as 'San Francisco Airport') published by access point; only
+ * available on passpoint network and if published by access point.
+ */
+ public CharSequence venueName;
+
+ /**
+ * Indicates passpoint operator name published by access point.
+ */
+ public CharSequence operatorFriendlyName;
/**
* {@hide}
@@ -267,7 +301,7 @@
**/
public byte[] bytes;
- /** information element from beacon
+ /** information elements from beacon
* @hide
*/
public static class InformationElement {
@@ -303,8 +337,7 @@
this.channelWidth = UNSPECIFIED;
this.centerFreq0 = UNSPECIFIED;
this.centerFreq1 = UNSPECIFIED;
- this.is80211McRTTResponder = false;
- this.passpointNetwork = false;
+ this.flags = 0;
}
/** {@hide} */
@@ -322,8 +355,7 @@
this.channelWidth = UNSPECIFIED;
this.centerFreq0 = UNSPECIFIED;
this.centerFreq1 = UNSPECIFIED;
- this.is80211McRTTResponder = false;
- this.passpointNetwork = false;
+ this.flags = 0;
}
/** {@hide} */
@@ -342,8 +374,11 @@
this.channelWidth = channelWidth;
this.centerFreq0 = centerFreq0;
this.centerFreq1 = centerFreq1;
- this.is80211McRTTResponder = is80211McRTTResponder;
- this.passpointNetwork = false;
+ if (is80211McRTTResponder) {
+ this.flags = FLAG_80211mc_RESPONDER;
+ } else {
+ this.flags = 0;
+ }
}
/** copy constructor {@hide} */
@@ -358,7 +393,6 @@
channelWidth = source.channelWidth;
centerFreq0 = source.centerFreq0;
centerFreq1 = source.centerFreq1;
- is80211McRTTResponder = source.is80211McRTTResponder;
timestamp = source.timestamp;
distanceCm = source.distanceCm;
distanceSdCm = source.distanceSdCm;
@@ -369,9 +403,9 @@
numUsage = source.numUsage;
numIpConfigFailures = source.numIpConfigFailures;
isAutoJoinCandidate = source.isAutoJoinCandidate;
- passpointNetwork = source.passpointNetwork;
venueName = source.venueName;
operatorFriendlyName = source.operatorFriendlyName;
+ flags = source.flags;
}
}
@@ -405,15 +439,16 @@
sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
append("(cm)");
- sb.append(", passpoint: ").append(passpointNetwork ? "yes" : "no");
+ sb.append(", passpoint: ");
+ sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no");
if (autoJoinStatus != 0) {
sb.append(", status: ").append(autoJoinStatus);
}
sb.append(", ChannelBandwidth: ").append(channelWidth);
sb.append(", centerFreq0: ").append(centerFreq0);
sb.append(", centerFreq1: ").append(centerFreq1);
- sb.append(", 80211mcResponder: ").append(is80211McRTTResponder?
- "is supported":"is not supported");
+ sb.append(", 80211mcResponder: ");
+ sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
return sb.toString();
}
@@ -440,7 +475,6 @@
dest.writeInt(channelWidth);
dest.writeInt(centerFreq0);
dest.writeInt(centerFreq1);
- dest.writeInt(is80211McRTTResponder ? 1 : 0);
dest.writeLong(seen);
dest.writeInt(autoJoinStatus);
dest.writeInt(untrusted ? 1 : 0);
@@ -448,9 +482,9 @@
dest.writeInt(numUsage);
dest.writeInt(numIpConfigFailures);
dest.writeInt(isAutoJoinCandidate);
- dest.writeInt(passpointNetwork ? 1 : 0);
- dest.writeString(venueName);
- dest.writeString(operatorFriendlyName);
+ dest.writeString((venueName != null) ? venueName.toString() : "");
+ dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : "");
+ dest.writeLong(this.flags);
if (informationElements != null) {
dest.writeInt(informationElements.length);
@@ -474,18 +508,19 @@
}
ScanResult sr = new ScanResult(
wifiSsid,
- in.readString(),
- in.readString(),
- in.readInt(),
- in.readInt(),
- in.readLong(),
- in.readInt(),
- in.readInt(),
- in.readInt(),
- in.readInt(),
- in.readInt(),
- in.readInt() == 1
+ in.readString(), /* BSSID */
+ in.readString(), /* capabilities */
+ in.readInt(), /* level */
+ in.readInt(), /* frequency */
+ in.readLong(), /* timestamp */
+ in.readInt(), /* distanceCm */
+ in.readInt(), /* distanceSdCm */
+ in.readInt(), /* channelWidth */
+ in.readInt(), /* centerFreq0 */
+ in.readInt(), /* centerFreq1 */
+ false /* rtt responder, fixed with flags below */
);
+
sr.seen = in.readLong();
sr.autoJoinStatus = in.readInt();
sr.untrusted = in.readInt() != 0;
@@ -493,9 +528,9 @@
sr.numUsage = in.readInt();
sr.numIpConfigFailures = in.readInt();
sr.isAutoJoinCandidate = in.readInt();
- sr.passpointNetwork = in.readInt() == 1;
sr.venueName = in.readString();
sr.operatorFriendlyName = in.readString();
+ sr.flags = in.readLong();
int n = in.readInt();
if (n != 0) {
sr.informationElements = new InformationElement[n];
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 5d55ec6..5d834f6 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -344,14 +344,15 @@
public String FQDN;
/**
- * Service provider name, for Passpoint credential.
+ * Name of passpoint credential provider
*/
public String providerFriendlyName;
/**
- * Roaming Consortium Id, for Passpoint credential.
+ * Roaming Consortium Id list for passpoint credential; identifies a set of networks where
+ * passpoint credential will be considered valid
*/
- public HashSet<Long> roamingConsortiumIds;
+ public Long[] roamingConsortiumIds;
/**
* @hide
@@ -906,7 +907,7 @@
SSID = null;
BSSID = null;
FQDN = null;
- roamingConsortiumIds = new HashSet<Long>();
+ roamingConsortiumIds = new Long[0];
priority = 0;
hiddenSSID = false;
disableReason = DISABLED_UNKNOWN_REASON;
@@ -1437,11 +1438,7 @@
SSID = source.SSID;
BSSID = source.BSSID;
FQDN = source.FQDN;
- roamingConsortiumIds = new HashSet<Long>();
- for (Long roamingConsortiumId : source.roamingConsortiumIds) {
- roamingConsortiumIds.add(roamingConsortiumId);
- }
-
+ roamingConsortiumIds = source.roamingConsortiumIds.clone();
providerFriendlyName = source.providerFriendlyName;
preSharedKey = source.preSharedKey;
@@ -1546,7 +1543,7 @@
dest.writeString(autoJoinBSSID);
dest.writeString(FQDN);
dest.writeString(providerFriendlyName);
- dest.writeInt(roamingConsortiumIds.size());
+ dest.writeInt(roamingConsortiumIds.length);
for (Long roamingConsortiumId : roamingConsortiumIds) {
dest.writeLong(roamingConsortiumId);
}
@@ -1622,8 +1619,9 @@
config.FQDN = in.readString();
config.providerFriendlyName = in.readString();
int numRoamingConsortiumIds = in.readInt();
+ config.roamingConsortiumIds = new Long[numRoamingConsortiumIds];
for (int i = 0; i < numRoamingConsortiumIds; i++) {
- config.roamingConsortiumIds.add(in.readLong());
+ config.roamingConsortiumIds[i] = in.readLong();
}
config.preSharedKey = in.readString();
for (int i = 0; i < config.wepKeys.length; i++) {
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 3525ec2..e611ea4 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -604,12 +604,13 @@
* Get the domain_suffix_match value. See setDomSuffixMatch.
* @return The domain value.
*/
- public String getDomainSubjectMatch() {
+ public String getDomainSuffixMatch() {
return getFieldValue(DOM_SUFFIX_MATCH_KEY, "");
}
/**
- * Set realm for passpoint credential
+ * Set realm for passpoint credential; realm identifies a set of networks where your
+ * passpoint credential can be used
* @param realm the realm
*/
public void setRealm(String realm) {
@@ -617,7 +618,7 @@
}
/**
- * Get realm for passpoint credential
+ * Get realm for passpoint credential; see {@link #setRealm(String)} for more information
* @return the realm
*/
public String getRealm() {
@@ -625,15 +626,16 @@
}
/**
- * Set plmn for passpoint credential
- * @param plmn the plmn value derived from mcc & mnc
+ * Set plmn (Public Land Mobile Network) of the provider of passpoint credential
+ * @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code)
*/
public void setPlmn(String plmn) {
setFieldValue(PLMN_KEY, plmn, "");
}
/**
- * Get plmn for passpoint credential
+ * Get plmn (Public Land Mobile Network) for passpoint credential; see {@link #setPlmn
+ * (String)} for more information
* @return the plmn
*/
public String getPlmn() {
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index dbfd4ef..2ba38e1 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -167,15 +167,24 @@
long txbad = stats.lostmpdu_be + stats.lostmpdu_bk
+ stats.lostmpdu_vi + stats.lostmpdu_vo;
- txBadRate = (txBadRate * 0.5)
- + ((double) (txbad - txBad) * 0.5);
- txSuccessRate = (txSuccessRate * 0.5)
- + ((double) (txgood - txSuccess) * 0.5);
- rxSuccessRate = (rxSuccessRate * 0.5)
- + ((double) (rxgood - rxSuccess) * 0.5);
- txRetriesRate = (txRetriesRate * 0.5)
- + ((double) (txretries - txRetries) * 0.5);
-
+ if (txBad <= txbad
+ && txSuccess <= txgood
+ && rxSuccess <= rxgood
+ && txRetries <= txretries) {
+ txBadRate = (txBadRate * 0.5)
+ + ((double) (txbad - txBad) * 0.5);
+ txSuccessRate = (txSuccessRate * 0.5)
+ + ((double) (txgood - txSuccess) * 0.5);
+ rxSuccessRate = (rxSuccessRate * 0.5)
+ + ((double) (rxgood - rxSuccess) * 0.5);
+ txRetriesRate = (txRetriesRate * 0.5)
+ + ((double) (txretries - txRetries) * 0.5);
+ } else {
+ txBadRate = 0;
+ txSuccessRate = 0;
+ rxSuccessRate = 0;
+ txRetriesRate = 0;
+ }
txBad = txbad;
txSuccess = txgood;
rxSuccess = rxgood;
@@ -204,11 +213,15 @@
txRetries = 0;
txBadRate = 0;
txRetriesRate = 0;
-
- txSuccessRate = (txSuccessRate * 0.5)
- + ((double) (txPackets - txSuccess) * 0.5);
- rxSuccessRate = (rxSuccessRate * 0.5)
- + ((double) (rxPackets - rxSuccess) * 0.5);
+ if (txSuccess <= txPackets && rxSuccess <= rxPackets) {
+ txSuccessRate = (txSuccessRate * 0.5)
+ + ((double) (txPackets - txSuccess) * 0.5);
+ rxSuccessRate = (rxSuccessRate * 0.5)
+ + ((double) (rxPackets - rxSuccess) * 0.5);
+ } else {
+ txBadRate = 0;
+ txRetriesRate = 0;
+ }
txSuccess = txPackets;
rxSuccess = rxPackets;
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 64fa0e5..d00c654 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -399,14 +399,16 @@
public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
/**
* An access point scan has completed, and results are available from the supplicant.
- * Call {@link #getScanResults()} to obtain the results.
+ * Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED}
+ * indicates if the scan was completed successfully.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
/**
- * The result of previous scan, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}.
- * @return true scan was successful, results updated
+ * Lookup key for a {@code boolean} representing the result of previous {@link #startScan}
+ * operation, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}.
+ * @return true scan was successful, results are updated
* @return false scan was not successful, results haven't been updated since previous scan
*/
public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";