Merge "Resolve CompoundButton's foreground drawable for layout direction change" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 90e44e7..376c2c3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10,10 +10,8 @@
field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
field public static final java.lang.String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
- field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
field public static final java.lang.String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
field public static final java.lang.String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
- field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
@@ -42,7 +40,6 @@
field public static final java.lang.String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
field public static final java.lang.String BODY_SENSORS = "android.permission.BODY_SENSORS";
- field public static final java.lang.String BRICK = "android.permission.BRICK";
field public static final java.lang.String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
field public static final java.lang.String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
field public static final java.lang.String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
@@ -59,33 +56,25 @@
field public static final java.lang.String CHANGE_WIFI_MULTICAST_STATE = "android.permission.CHANGE_WIFI_MULTICAST_STATE";
field public static final java.lang.String CHANGE_WIFI_STATE = "android.permission.CHANGE_WIFI_STATE";
field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
- field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
field public static final java.lang.String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
field public static final java.lang.String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
- field public static final java.lang.String DEVICE_POWER = "android.permission.DEVICE_POWER";
field public static final java.lang.String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
field public static final java.lang.String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
field public static final java.lang.String DUMP = "android.permission.DUMP";
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
field public static final java.lang.String FLASHLIGHT = "android.permission.FLASHLIGHT";
- field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
- field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
- field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
- field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
field public static final java.lang.String INSTALL_SHORTCUT = "com.android.launcher.permission.INSTALL_SHORTCUT";
- field public static final java.lang.String INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW";
field public static final java.lang.String INTERNET = "android.permission.INTERNET";
field public static final java.lang.String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
- field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
@@ -105,12 +94,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";
@@ -123,13 +109,10 @@
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
- field public static final java.lang.String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
- field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION";
- field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
field public static final deprecated java.lang.String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
field public static final java.lang.String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
field public static final java.lang.String SET_TIME = "android.permission.SET_TIME";
@@ -152,12 +135,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 +152,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 {
@@ -2112,22 +2090,6 @@
field public static final int Theme_Light_Panel = 16973914; // 0x103005a
field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
field public static final int Theme_Material = 16974372; // 0x1030224
- field public static final int Theme_Material_DayNight = 16974548; // 0x10302d4
- field public static final int Theme_Material_DayNight_DarkActionBar = 16974549; // 0x10302d5
- field public static final int Theme_Material_DayNight_Dialog = 16974550; // 0x10302d6
- field public static final int Theme_Material_DayNight_DialogWhenLarge = 16974556; // 0x10302dc
- field public static final int Theme_Material_DayNight_DialogWhenLarge_DarkActionBar = 16974568; // 0x10302e8
- field public static final int Theme_Material_DayNight_DialogWhenLarge_NoActionBar = 16974557; // 0x10302dd
- field public static final int Theme_Material_DayNight_Dialog_Alert = 16974551; // 0x10302d7
- field public static final int Theme_Material_DayNight_Dialog_MinWidth = 16974552; // 0x10302d8
- field public static final int Theme_Material_DayNight_Dialog_NoActionBar = 16974553; // 0x10302d9
- field public static final int Theme_Material_DayNight_Dialog_NoActionBar_MinWidth = 16974554; // 0x10302da
- field public static final int Theme_Material_DayNight_Dialog_Presentation = 16974555; // 0x10302db
- field public static final int Theme_Material_DayNight_NoActionBar = 16974558; // 0x10302de
- field public static final int Theme_Material_DayNight_NoActionBar_Fullscreen = 16974559; // 0x10302df
- field public static final int Theme_Material_DayNight_NoActionBar_Overscan = 16974560; // 0x10302e0
- field public static final int Theme_Material_DayNight_NoActionBar_TranslucentDecor = 16974561; // 0x10302e1
- field public static final int Theme_Material_DayNight_Panel = 16974562; // 0x10302e2
field public static final int Theme_Material_Dialog = 16974373; // 0x1030225
field public static final int Theme_Material_DialogWhenLarge = 16974379; // 0x103022b
field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974380; // 0x103022c
@@ -2141,7 +2103,6 @@
field public static final int Theme_Material_Light_DarkActionBar = 16974392; // 0x1030238
field public static final int Theme_Material_Light_Dialog = 16974393; // 0x1030239
field public static final int Theme_Material_Light_DialogWhenLarge = 16974399; // 0x103023f
- field public static final int Theme_Material_Light_DialogWhenLarge_DarkActionBar = 16974567; // 0x10302e7
field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974400; // 0x1030240
field public static final int Theme_Material_Light_Dialog_Alert = 16974394; // 0x103023a
field public static final int Theme_Material_Light_Dialog_MinWidth = 16974395; // 0x103023b
@@ -2597,6 +2558,21 @@
field public static final int Widget_Toolbar = 16974311; // 0x10301e7
field public static final int Widget_Toolbar_Button_Navigation = 16974312; // 0x10301e8
field public static final int Widget_WebView = 16973875; // 0x1030033
+ field public static final int __reserved10 = 16974550; // 0x10302d6
+ field public static final int __reserved11 = 16974551; // 0x10302d7
+ field public static final int __reserved12 = 16974552; // 0x10302d8
+ field public static final int __reserved13 = 16974553; // 0x10302d9
+ field public static final int __reserved14 = 16974554; // 0x10302da
+ field public static final int __reserved15 = 16974555; // 0x10302db
+ field public static final int __reserved16 = 16974556; // 0x10302dc
+ field public static final int __reserved17 = 16974557; // 0x10302dd
+ field public static final int __reserved18 = 16974558; // 0x10302de
+ field public static final int __reserved19 = 16974559; // 0x10302df
+ field public static final int __reserved20 = 16974560; // 0x10302e0
+ field public static final int __reserved21 = 16974561; // 0x10302e1
+ field public static final int __reserved22 = 16974562; // 0x10302e2
+ field public static final int __reserved8 = 16974548; // 0x10302d4
+ field public static final int __reserved9 = 16974549; // 0x10302d5
}
public static final class R.transition {
@@ -3903,6 +3879,7 @@
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -3915,6 +3892,7 @@
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -4018,79 +3996,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);
@@ -4812,7 +4717,6 @@
method public android.graphics.drawable.Icon getLargeIcon();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
- method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -5699,7 +5603,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";
@@ -5711,12 +5614,11 @@
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);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -5761,7 +5663,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);
@@ -5780,7 +5681,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);
@@ -5813,7 +5713,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);
@@ -5842,12 +5741,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";
@@ -5873,7 +5766,6 @@
field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8
field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1
field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
- field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC_V2 = "application/com.android.managedprovisioning.v2";
field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
@@ -5913,22 +5805,90 @@
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 float getAlpha();
+ 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 float getElevation();
+ 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 android.graphics.Matrix getTransformation();
+ 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 {
@@ -7224,6 +7184,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
@@ -12321,7 +12282,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();
@@ -12341,7 +12301,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);
@@ -12482,6 +12442,9 @@
method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
method public void loadDrawableAsync(android.content.Context, android.os.Message);
method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
+ method public android.graphics.drawable.Icon setTint(int);
+ method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList);
+ method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
}
@@ -13518,7 +13481,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
@@ -13871,6 +13833,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();
@@ -15865,6 +15828,10 @@
ctor public MediaDrmException(java.lang.String);
}
+ public class MediaDrmResetException extends java.lang.IllegalStateException {
+ ctor public MediaDrmResetException(java.lang.String);
+ }
+
public final class MediaExtractor {
ctor public MediaExtractor();
method public boolean advance();
@@ -17696,6 +17663,11 @@
public static final class TvContract.Channels implements android.media.tv.TvContract.BaseTvColumns {
method public static final java.lang.String getVideoResolution(java.lang.String);
+ field public static final java.lang.String COLUMN_APP_LINK_COLOR = "app_link_color";
+ field public static final java.lang.String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
field public static final java.lang.String COLUMN_DESCRIPTION = "description";
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
@@ -17782,6 +17754,7 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
@@ -18164,6 +18137,7 @@
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
method public deprecated void reportBadNetwork(android.net.Network);
@@ -18209,7 +18183,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 {
@@ -18360,6 +18333,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
@@ -18374,6 +18348,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
@@ -19087,6 +19062,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
@@ -19094,18 +19071,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 {
@@ -19148,7 +19126,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;
@@ -19210,7 +19188,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();
@@ -22723,7 +22701,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 10000; // 0x2710
+ field public static final int MNC = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -22824,6 +22802,7 @@
public class DeadObjectException extends android.os.RemoteException {
ctor public DeadObjectException();
+ ctor public DeadObjectException(java.lang.String);
}
public final class Debug {
@@ -23665,6 +23644,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_PROFILE_APP_LINKING = "allow_parent_profile_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";
@@ -25577,10 +25557,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";
@@ -25896,10 +25872,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";
@@ -25970,56 +25942,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";
@@ -26504,6 +26426,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
@@ -26583,6 +26506,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";
@@ -27922,8 +27846,6 @@
public static final class ScriptGroup.Binding {
ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
- method public android.renderscript.Script.FieldID getField();
- method public java.lang.Object getValue();
}
public static final deprecated class ScriptGroup.Builder {
@@ -28074,18 +27996,6 @@
field public static final int UPPER = 121; // 0x79
}
- public static abstract class ScriptIntrinsicBLAS.Diag implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Side implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Transpose implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Uplo implements java.lang.annotation.Annotation {
- }
-
public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
@@ -28617,8 +28527,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 {
@@ -30545,7 +30454,7 @@
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
- field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
@@ -30565,6 +30474,7 @@
field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
@@ -30620,17 +30530,22 @@
field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
+ field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
- field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
+ field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
+ field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+ field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
- field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
+ field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
+ field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
@@ -30681,6 +30596,9 @@
field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
+ field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
+ field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
+ field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
@@ -31165,7 +31083,7 @@
method public java.lang.String getLine1Number();
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
- method public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
+ method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public java.lang.String getNetworkCountryIso();
method public java.lang.String getNetworkOperator();
method public java.lang.String getNetworkOperatorName();
@@ -31199,6 +31117,7 @@
method public boolean setOperatorBrandOverride(java.lang.String);
method public boolean setPreferredNetworkTypeToGlobal();
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+ field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
field public static final int CALL_STATE_IDLE = 0; // 0x0
@@ -31244,6 +31163,8 @@
field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3
field public static final int SIM_STATE_READY = 5; // 0x5
field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
+ field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
+ field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
}
@@ -34573,6 +34494,7 @@
method public abstract void invalidate();
method public void invalidateContentRect();
method public boolean isTitleOptional();
+ method public void onWindowFocusChanged(boolean);
method public abstract void setCustomView(android.view.View);
method public abstract void setSubtitle(java.lang.CharSequence);
method public abstract void setSubtitle(int);
@@ -34874,6 +34796,7 @@
field public static final deprecated int MOTION_RANGE_X = 0; // 0x0
field public static final deprecated int MOTION_RANGE_Y = 1; // 0x1
field public static final int SOURCE_ANY = -256; // 0xffffff00
+ field public static final int SOURCE_BLUETOOTH_STYLUS = 49154; // 0xc002
field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
field public static final int SOURCE_CLASS_MASK = 255; // 0xff
@@ -36639,10 +36562,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);
@@ -37024,7 +36943,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();
@@ -37032,9 +36951,10 @@
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 setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -37043,6 +36963,7 @@
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -37053,6 +36974,7 @@
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
@@ -37545,6 +37467,7 @@
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
diff --git a/api/removed.txt b/api/removed.txt
index 2e6c685..6d88cb6 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,3 +1,11 @@
+package android.app {
+
+ public class Notification implements android.os.Parcelable {
+ method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
+ }
+
+}
+
package android.content.pm {
public class PackageInfo implements android.os.Parcelable {
@@ -117,6 +125,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 8a99eaf..57f3a30 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -96,6 +96,7 @@
field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
+ field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
@@ -155,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";
@@ -226,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";
}
@@ -246,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 {
@@ -2194,22 +2187,6 @@
field public static final int Theme_Light_Panel = 16973914; // 0x103005a
field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
field public static final int Theme_Material = 16974372; // 0x1030224
- field public static final int Theme_Material_DayNight = 16974548; // 0x10302d4
- field public static final int Theme_Material_DayNight_DarkActionBar = 16974549; // 0x10302d5
- field public static final int Theme_Material_DayNight_Dialog = 16974550; // 0x10302d6
- field public static final int Theme_Material_DayNight_DialogWhenLarge = 16974556; // 0x10302dc
- field public static final int Theme_Material_DayNight_DialogWhenLarge_DarkActionBar = 16974568; // 0x10302e8
- field public static final int Theme_Material_DayNight_DialogWhenLarge_NoActionBar = 16974557; // 0x10302dd
- field public static final int Theme_Material_DayNight_Dialog_Alert = 16974551; // 0x10302d7
- field public static final int Theme_Material_DayNight_Dialog_MinWidth = 16974552; // 0x10302d8
- field public static final int Theme_Material_DayNight_Dialog_NoActionBar = 16974553; // 0x10302d9
- field public static final int Theme_Material_DayNight_Dialog_NoActionBar_MinWidth = 16974554; // 0x10302da
- field public static final int Theme_Material_DayNight_Dialog_Presentation = 16974555; // 0x10302db
- field public static final int Theme_Material_DayNight_NoActionBar = 16974558; // 0x10302de
- field public static final int Theme_Material_DayNight_NoActionBar_Fullscreen = 16974559; // 0x10302df
- field public static final int Theme_Material_DayNight_NoActionBar_Overscan = 16974560; // 0x10302e0
- field public static final int Theme_Material_DayNight_NoActionBar_TranslucentDecor = 16974561; // 0x10302e1
- field public static final int Theme_Material_DayNight_Panel = 16974562; // 0x10302e2
field public static final int Theme_Material_Dialog = 16974373; // 0x1030225
field public static final int Theme_Material_DialogWhenLarge = 16974379; // 0x103022b
field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974380; // 0x103022c
@@ -2223,7 +2200,6 @@
field public static final int Theme_Material_Light_DarkActionBar = 16974392; // 0x1030238
field public static final int Theme_Material_Light_Dialog = 16974393; // 0x1030239
field public static final int Theme_Material_Light_DialogWhenLarge = 16974399; // 0x103023f
- field public static final int Theme_Material_Light_DialogWhenLarge_DarkActionBar = 16974567; // 0x10302e7
field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974400; // 0x1030240
field public static final int Theme_Material_Light_Dialog_Alert = 16974394; // 0x103023a
field public static final int Theme_Material_Light_Dialog_MinWidth = 16974395; // 0x103023b
@@ -2679,6 +2655,21 @@
field public static final int Widget_Toolbar = 16974311; // 0x10301e7
field public static final int Widget_Toolbar_Button_Navigation = 16974312; // 0x10301e8
field public static final int Widget_WebView = 16973875; // 0x1030033
+ field public static final int __reserved10 = 16974550; // 0x10302d6
+ field public static final int __reserved11 = 16974551; // 0x10302d7
+ field public static final int __reserved12 = 16974552; // 0x10302d8
+ field public static final int __reserved13 = 16974553; // 0x10302d9
+ field public static final int __reserved14 = 16974554; // 0x10302da
+ field public static final int __reserved15 = 16974555; // 0x10302db
+ field public static final int __reserved16 = 16974556; // 0x10302dc
+ field public static final int __reserved17 = 16974557; // 0x10302dd
+ field public static final int __reserved18 = 16974558; // 0x10302de
+ field public static final int __reserved19 = 16974559; // 0x10302df
+ field public static final int __reserved20 = 16974560; // 0x10302e0
+ field public static final int __reserved21 = 16974561; // 0x10302e1
+ field public static final int __reserved22 = 16974562; // 0x10302e2
+ field public static final int __reserved8 = 16974548; // 0x10302d4
+ field public static final int __reserved9 = 16974549; // 0x10302d5
}
public static final class R.transition {
@@ -3998,6 +3989,7 @@
field public static final java.lang.String OPSTR_READ_CALL_LOG = "android:read_call_log";
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
+ field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4010,6 +4002,7 @@
field public static final java.lang.String OPSTR_WRITE_CALENDAR = "android:write_calendar";
field public static final java.lang.String OPSTR_WRITE_CALL_LOG = "android:write_call_log";
field public static final java.lang.String OPSTR_WRITE_CONTACTS = "android:write_contacts";
+ field public static final java.lang.String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage";
}
public static abstract interface AppOpsManager.OnOpChangedListener {
@@ -4113,79 +4106,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);
@@ -4913,7 +4833,6 @@
method public android.graphics.drawable.Icon getLargeIcon();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
- method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -5804,7 +5723,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";
@@ -5816,13 +5734,12 @@
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);
method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
- method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
- method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+ method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
method public void enableSystemApp(android.content.ComponentName, java.lang.String);
method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
method public java.lang.String[] getAccountTypesWithManagementDisabled();
@@ -5874,7 +5791,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);
@@ -5895,7 +5811,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);
@@ -5928,7 +5843,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);
@@ -5959,12 +5873,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";
@@ -5990,7 +5898,6 @@
field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8
field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1
field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
- field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC_V2 = "application/com.android.managedprovisioning.v2";
field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
@@ -6030,22 +5937,90 @@
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 float getAlpha();
+ 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 float getElevation();
+ 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 android.graphics.Matrix getTransformation();
+ 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 {
@@ -7448,6 +7423,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
@@ -12646,7 +12622,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();
@@ -12666,7 +12641,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);
@@ -12807,6 +12782,9 @@
method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
method public void loadDrawableAsync(android.content.Context, android.os.Message);
method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
+ method public android.graphics.drawable.Icon setTint(int);
+ method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList);
+ method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
}
@@ -13848,7 +13826,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
@@ -14201,6 +14178,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();
@@ -17119,6 +17097,10 @@
ctor public MediaDrmException(java.lang.String);
}
+ public class MediaDrmResetException extends java.lang.IllegalStateException {
+ ctor public MediaDrmResetException(java.lang.String);
+ }
+
public final class MediaExtractor {
ctor public MediaExtractor();
method public boolean advance();
@@ -19032,6 +19014,11 @@
public static final class TvContract.Channels implements android.media.tv.TvContract.BaseTvColumns {
method public static final java.lang.String getVideoResolution(java.lang.String);
+ field public static final java.lang.String COLUMN_APP_LINK_COLOR = "app_link_color";
+ field public static final java.lang.String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
field public static final java.lang.String COLUMN_DESCRIPTION = "description";
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
@@ -19120,6 +19107,7 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
@@ -19664,6 +19652,7 @@
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
method public deprecated void reportBadNetwork(android.net.Network);
@@ -19709,7 +19698,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 {
@@ -19860,6 +19848,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
@@ -19874,6 +19863,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
@@ -20828,6 +20818,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
@@ -20835,18 +20827,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 {
@@ -20896,7 +20889,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;
@@ -20973,7 +20966,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();
@@ -24655,7 +24648,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 10000; // 0x2710
+ field public static final int MNC = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -24756,6 +24749,7 @@
public class DeadObjectException extends android.os.RemoteException {
ctor public DeadObjectException();
+ ctor public DeadObjectException(java.lang.String);
}
public final class Debug {
@@ -25609,6 +25603,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_PROFILE_APP_LINKING = "allow_parent_profile_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";
@@ -27521,10 +27516,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";
@@ -27840,10 +27831,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";
@@ -27914,56 +27901,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";
@@ -28550,6 +28487,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
@@ -28630,6 +28568,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";
@@ -29969,8 +29908,6 @@
public static final class ScriptGroup.Binding {
ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
- method public android.renderscript.Script.FieldID getField();
- method public java.lang.Object getValue();
}
public static final deprecated class ScriptGroup.Builder {
@@ -30121,18 +30058,6 @@
field public static final int UPPER = 121; // 0x79
}
- public static abstract class ScriptIntrinsicBLAS.Diag implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Side implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Transpose implements java.lang.annotation.Annotation {
- }
-
- public static abstract class ScriptIntrinsicBLAS.Uplo implements java.lang.annotation.Annotation {
- }
-
public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
@@ -30664,8 +30589,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 {
@@ -32763,7 +32687,7 @@
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
- field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
@@ -32785,6 +32709,7 @@
field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
@@ -32842,17 +32767,22 @@
field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
+ field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
- field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
+ field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
+ field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+ field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
- field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
+ field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
+ field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
@@ -32903,6 +32833,9 @@
field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
+ field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
+ field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
+ field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
@@ -33406,7 +33339,7 @@
method public java.lang.String getLine1Number();
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
- method public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
+ method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public java.lang.String getNetworkCountryIso();
method public java.lang.String getNetworkOperator();
method public java.lang.String getNetworkOperatorName();
@@ -33461,6 +33394,7 @@
method public int[] supplyPukReportResult(java.lang.String, java.lang.String);
method public void toggleRadioOnOff();
method public void updateServiceLocation();
+ field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
field public static final int CALL_STATE_IDLE = 0; // 0x0
@@ -33515,6 +33449,8 @@
field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3
field public static final int SIM_STATE_READY = 5; // 0x5
field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
+ field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
+ field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
}
@@ -36853,6 +36789,7 @@
method public abstract void invalidate();
method public void invalidateContentRect();
method public boolean isTitleOptional();
+ method public void onWindowFocusChanged(boolean);
method public abstract void setCustomView(android.view.View);
method public abstract void setSubtitle(java.lang.CharSequence);
method public abstract void setSubtitle(int);
@@ -37154,6 +37091,7 @@
field public static final deprecated int MOTION_RANGE_X = 0; // 0x0
field public static final deprecated int MOTION_RANGE_Y = 1; // 0x1
field public static final int SOURCE_ANY = -256; // 0xffffff00
+ field public static final int SOURCE_BLUETOOTH_STYLUS = 49154; // 0xc002
field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
field public static final int SOURCE_CLASS_MASK = 255; // 0xff
@@ -38919,10 +38857,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);
@@ -39304,7 +39238,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();
@@ -39312,9 +39246,10 @@
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 setAlpha(float);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -39323,6 +39258,7 @@
method public abstract void setContentDescription(java.lang.CharSequence);
method public abstract void setContextClickable(boolean);
method public abstract void setDimens(int, int, int, int, int, int);
+ method public abstract void setElevation(float);
method public abstract void setEnabled(boolean);
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
@@ -39333,6 +39269,7 @@
method public abstract void setText(java.lang.CharSequence);
method public abstract void setText(java.lang.CharSequence, int, int);
method public abstract void setTextStyle(float, int, int, int);
+ method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
}
@@ -39828,6 +39765,7 @@
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 2e6c685..6d88cb6 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -1,3 +1,11 @@
+package android.app {
+
+ public class Notification implements android.os.Parcelable {
+ method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
+ }
+
+}
+
package android.content.pm {
public class PackageInfo implements android.os.Parcelable {
@@ -117,6 +125,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/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 69ba27c..13fda59 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1688,7 +1688,7 @@
private void runPackageImportance() throws Exception {
String packageName = nextArgRequired();
try {
- int procState = mAm.getPackageProcessState(packageName);
+ int procState = mAm.getPackageProcessState(packageName, "com.android.shell");
System.out.println(
ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
} catch (RemoteException e) {
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 3599695..7ce0846 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -1,5 +1,12 @@
LOCAL_PATH:= $(call my-dir)
+# This is a list of libraries that need to be included in order to avoid
+# bad apps. This prevents a library from having a mismatch when resolving
+# new/delete from an app shared library.
+# See b/21032018 for more details.
+app_process_common_shared_libs := \
+ libwilhelm \
+
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -13,7 +20,8 @@
libutils \
liblog \
libbinder \
- libandroid_runtime
+ libandroid_runtime \
+ $(app_process_common_shared_libs) \
LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
@@ -44,7 +52,8 @@
libutils \
liblog \
libbinder \
- libandroid_runtime
+ libandroid_runtime \
+ $(app_process_common_shared_libs) \
LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
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/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 2be44bc..ce83caa 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -204,6 +204,10 @@
return runGrantRevokePermission(false);
}
+ if ("reset-permissions".equals(op)) {
+ return runResetPermissions();
+ }
+
if ("set-permission-enforced".equals(op)) {
return runSetPermissionEnforced();
}
@@ -1636,6 +1640,24 @@
}
}
+ private int runResetPermissions() {
+ try {
+ mPm.resetRuntimePermissions();
+ return 0;
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
+ } catch (IllegalArgumentException e) {
+ System.err.println("Bad argument: " + e.toString());
+ showUsage();
+ return 1;
+ } catch (SecurityException e) {
+ System.err.println("Operation not allowed: " + e.toString());
+ return 1;
+ }
+ }
+
private int runSetPermissionEnforced() {
final String permission = nextArg();
if (permission == null) {
@@ -1911,6 +1933,7 @@
System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION");
+ System.err.println(" pm reset-permissions");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
@@ -1988,6 +2011,8 @@
System.err.println(" manifest, be runtime permissions (protection level dangerous),");
System.err.println(" and the app targeting SDK greater than Lollipop MR1.");
System.err.println("");
+ System.err.println("pm reset-permissions: revert all runtime permissions to their default state.");
+ System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
System.err.println(" 1 [internal]: Install on internal device storage");
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..9c2e208 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());
@@ -6470,20 +6473,22 @@
}
private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
- String[] permissions = data.getStringArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
- final int[] grantResults = data.getIntArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
+ // If the package installer crashed we may have not data - best effort.
+ String[] permissions = (data != null) ? data.getStringArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
+ final int[] grantResults = (data != null) ? data.getIntArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data,
- Fragment fragement) {
- String[] permissions = data.getStringArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
- final int[] grantResults = data.getIntArrayExtra(
- PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS);
- fragement.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ Fragment fragment) {
+ // If the package installer crashed we may have not data - best effort.
+ String[] permissions = (data != null) ? data.getStringArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
+ final int[] grantResults = (data != null) ? data.getIntArrayExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
+ fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
class HostCallbacks extends FragmentHostCallback<Activity> {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b65593d..9ca206a4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2345,7 +2345,8 @@
@SystemApi
public int getPackageImportance(String packageName) {
try {
- int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName);
+ int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName,
+ mContext.getOpPackageName());
return RunningAppProcessInfo.procStateToImportance(procState);
} catch (RemoteException e) {
return RunningAppProcessInfo.IMPORTANCE_GONE;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 680feae..2bb4e76 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2217,6 +2217,14 @@
return true;
}
+ case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ boolean res = isScreenCaptureAllowedOnCurrentActivity();
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case KILL_UID_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int uid = data.readInt();
@@ -2539,7 +2547,8 @@
case GET_PACKAGE_PROCESS_STATE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String pkg = data.readString();
- int res = getPackageProcessState(pkg);
+ String callingPackage = data.readString();
+ int res = getPackageProcessState(pkg, callingPackage);
reply.writeNoException();
reply.writeInt(res);
return true;
@@ -5408,6 +5417,18 @@
return res;
}
+ public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void killUid(int uid, String reason) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -5868,11 +5889,13 @@
}
@Override
- public int getPackageProcessState(String packageName) throws RemoteException {
+ public int getPackageProcessState(String packageName, String callingPackage)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(packageName);
+ data.writeString(callingPackage);
mRemote.transact(GET_PACKAGE_PROCESS_STATE_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8a61ec6..9faadd3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -229,8 +229,12 @@
public static final int OP_READ_CELL_BROADCASTS = 57;
/** @hide Inject mock location into the system. */
public static final int OP_MOCK_LOCATION = 58;
+ /** @hide Read external storage. */
+ public static final int OP_READ_EXTERNAL_STORAGE = 59;
+ /** @hide Write external storage. */
+ public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
/** @hide */
- public static final int _NUM_OP = 59;
+ public static final int _NUM_OP = 61;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -313,6 +317,12 @@
/** Inject mock location into the system. */
public static final String OPSTR_MOCK_LOCATION
= "android:mock_location";
+ /** Read external storage. */
+ public static final String OPSTR_READ_EXTERNAL_STORAGE
+ = "android:read_external_storage";
+ /** Write external storage. */
+ public static final String OPSTR_WRITE_EXTERNAL_STORAGE
+ = "android:write_external_storage";
/**
* This maps each operation to the operation that serves as the
@@ -381,7 +391,9 @@
OP_USE_FINGERPRINT,
OP_BODY_SENSORS,
OP_READ_CELL_BROADCASTS,
- OP_MOCK_LOCATION
+ OP_MOCK_LOCATION,
+ OP_READ_EXTERNAL_STORAGE,
+ OP_WRITE_EXTERNAL_STORAGE
};
/**
@@ -447,7 +459,9 @@
OPSTR_USE_FINGERPRINT,
OPSTR_BODY_SENSORS,
OPSTR_READ_CELL_BROADCASTS,
- OPSTR_MOCK_LOCATION
+ OPSTR_MOCK_LOCATION,
+ OPSTR_READ_EXTERNAL_STORAGE,
+ OPSTR_WRITE_EXTERNAL_STORAGE
};
/**
@@ -513,7 +527,9 @@
"USE_FINGERPRINT",
"BODY_SENSORS",
"READ_CELL_BROADCASTS",
- "MOCK_LOCATION"
+ "MOCK_LOCATION",
+ "OPSTR_READ_EXTERNAL_STORAGE",
+ "OPSTR_WRITE_EXTERNAL_STORAGE",
};
/**
@@ -579,7 +595,9 @@
Manifest.permission.USE_FINGERPRINT,
Manifest.permission.BODY_SENSORS,
Manifest.permission.READ_CELL_BROADCASTS,
- null
+ null,
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
/**
@@ -646,7 +664,9 @@
null, // USE_FINGERPRINT
null, // BODY_SENSORS
null, // READ_CELL_BROADCASTS
- null // MOCK_LOCATION
+ null, // MOCK_LOCATION
+ null, // READ_EXTERNAL_STORAGE
+ null // WRITE_EXTERNAL_STORAGE
};
/**
@@ -712,7 +732,9 @@
false, // USE_FINGERPRINT
false, // BODY_SENSORS
false, // READ_CELL_BROADCASTS
- false // MOCK_LOCATION
+ false, // MOCK_LOCATION
+ false, // READ_EXTERNAL_STORAGE
+ false // WRITE_EXTERNAL_STORAGE
};
/**
@@ -777,7 +799,9 @@
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ERRORED // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION
+ AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_ALLOWED
};
/**
@@ -846,6 +870,8 @@
false,
false,
false,
+ false,
+ false,
false
};
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 1461380..e178087 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -35,6 +35,9 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
+import android.os.TransactionTooLargeException;
+import android.util.Log;
+
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
@@ -921,8 +924,13 @@
info.writeToParcel(data, 0);
compatInfo.writeToParcel(data, 0);
data.writeInt(processState);
- mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
- IBinder.FLAG_ONEWAY);
+ try {
+ mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
+ IBinder.FLAG_ONEWAY);
+ } catch (TransactionTooLargeException e) {
+ Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
+ throw e;
+ }
data.recycle();
}
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/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 903411e..13030ca 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -717,6 +717,7 @@
break;
case OP_REPLACE: {
Fragment f = op.fragment;
+ int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
@@ -724,7 +725,7 @@
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
- if (f == null || old.mContainerId == f.mContainerId) {
+ if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index e7f7e13..1423e4b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -441,6 +441,8 @@
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) throws RemoteException;
+ public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException;
+
public void killUid(int uid, String reason) throws RemoteException;
public void hang(IBinder who, boolean allowRestart) throws RemoteException;
@@ -503,7 +505,8 @@
public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException;
public void updateDeviceOwner(String packageName) throws RemoteException;
- public int getPackageProcessState(String packageName) throws RemoteException;
+ public int getPackageProcessState(String packageName, String callingPackage)
+ throws RemoteException;
public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
throws RemoteException;
@@ -851,4 +854,6 @@
int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
int REGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
+ int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
+ = IBinder.FIRST_CALL_TRANSACTION+299;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5a0d246..c3dece8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1749,6 +1749,7 @@
* Stack</a> document.
*
* @deprecated Use {@link Builder} instead.
+ * @removed
*/
@Deprecated
public void setLatestEventInfo(Context context,
@@ -3586,12 +3587,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 +3798,11 @@
return wip;
}
+ /**
+ * @hide
+ */
+ public void purgeResources() {}
+
// The following methods are split out so we can re-create notification partially.
/**
* @hide
@@ -3901,8 +3914,21 @@
return this;
}
- private RemoteViews makeBigContentView() {
+ /**
+ * @hide
+ */
+ @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..d28ff51 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -215,7 +215,7 @@
* <p>This component is set as device owner and active admin when device owner provisioning is
* started by an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE} or by an NFC
* message containing an NFC record with MIME type
- * {@link #MIME_TYPE_PROVISIONING_NFC_V2}. For the NFC record, the component name should be
+ * {@link #MIME_TYPE_PROVISIONING_NFC}. For the NFC record, the component name should be
* flattened to a string, via {@link ComponentName#flattenToShortString()}.
*
* @see DeviceAdminReceiver
@@ -386,7 +386,7 @@
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} if the version of the
* installed package is less than this version code.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE
@@ -461,13 +461,14 @@
* A boolean extra indicating whether device encryption can be skipped as part of Device Owner
* provisioning.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} or an intent with action
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} or an intent with action
* {@link #ACTION_PROVISION_MANAGED_DEVICE} that starts device owner provisioning.
*/
public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION =
"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}.
@@ -552,12 +558,17 @@
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM";
/**
- * This MIME type is used for starting the Device Owner provisioning that does not require
- * provisioning features introduced in Android API level
- * {@link android.os.Build.VERSION_CODES#MNC} or later levels.
+ * This MIME type is used for starting the Device Owner provisioning.
*
- * <p>For more information about the provisioning process see
- * {@link #MIME_TYPE_PROVISIONING_NFC_V2}.
+ * <p>During device owner provisioning a device admin app is set as the owner of the device.
+ * A device owner has full control over the device. The device owner can not be modified by the
+ * user and the only way of resetting the device is if the device owner app calls a factory
+ * reset.
+ *
+ * <p> A typical use case would be a device that is owned by a company, but used by either an
+ * employee or client.
+ *
+ * <p> The NFC message should be send to an unprovisioned device.
*
* <p>The NFC record must contain a serialized {@link java.util.Properties} object which
* contains the following properties:
@@ -583,15 +594,13 @@
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
- *
- * @see #MIME_TYPE_PROVISIONING_NFC_V2
- *
*/
public static final String MIME_TYPE_PROVISIONING_NFC
= "application/com.android.managedprovisioning";
/**
+ * @hide
* This MIME type is used for starting the Device Owner provisioning that requires
* new provisioning features introduced in API version
* {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
@@ -611,11 +620,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
@@ -2401,6 +2405,9 @@
* <p>The calling device admin must be a device or profile owner. If it is not, a
* security exception will be thrown.
*
+ * <p>From version {@link android.os.Build.VERSION_CODES#MNC} disabling screen capture also
+ * blocks assist requests for all activities of the relevant user.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled Whether screen capture is disabled or not.
*/
@@ -2756,6 +2763,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 +2792,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 +2811,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 +2866,7 @@
/**
+ * @hide
* Sets the enabled state of the user. A user should be enabled only once it is ready to
* be used.
*
@@ -3601,7 +3612,10 @@
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createUser(@NonNull ComponentName admin, String name) {
try {
return mService.createUser(admin, name);
@@ -3635,7 +3649,10 @@
* @see UserHandle
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
+ *
+ * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
*/
+ @Deprecated
public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
try {
@@ -3951,22 +3968,26 @@
* <li>{@link Settings.Global#ADB_ENABLED}</li>
* <li>{@link Settings.Global#AUTO_TIME}</li>
* <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
- * <li>{@link Settings.Global#BLUETOOTH_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.bluetooth.BluetoothAdapter#enable()} and
- * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
* <li>{@link Settings.Global#DATA_ROAMING}</li>
- * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
- * <li>{@link Settings.Global#MODE_RINGER}</li>
- * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
* <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
- * <li>{@link Settings.Global#WIFI_ON}
- * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use
- * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
* <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
* <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>
+ * 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>
+ * <p>Changing the following settings has no effect as of
+ * {@link android.os.Build.VERSION_CODES#MNC}:
+ * <ul>
+ * <li>{@link Settings.Global#BLUETOOTH_ON}.
+ * Use {@link android.bluetooth.BluetoothAdapter#enable()} and
+ * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li>
+ * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+ * <li>{@link Settings.Global#MODE_RINGER}.
+ * Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li>
+ * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
+ * <li>{@link Settings.Global#WIFI_ON}.
+ * Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li>
* </ul>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -4326,7 +4347,7 @@
* @param admin Which profile or device owner this request is associated with.
* @return the current policy for future permission requests.
*/
- public int getPermissionPolicy(@NonNull ComponentName admin) {
+ public int getPermissionPolicy(ComponentName admin) {
try {
return mService.getPermissionPolicy(admin);
} catch (RemoteException re) {
@@ -4344,6 +4365,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..3429b6e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1,28 +1,1192 @@
package android.app.assist;
import android.app.Activity;
+import android.content.ComponentName;
+import android.graphics.Matrix;
+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, float[] tmpMatrix) {
+ 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, tmpMatrix);
+ }
+
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ TextUtils.writeToParcel(mTitle, out, 0);
+ out.writeInt(mDisplayId);
+ return mRoot.writeToParcel(out, pwriter, tmpMatrix);
+ }
+
+ /**
+ * 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 = View.NO_ID;
+ String mIdPackage;
+ String mIdType;
+ String mIdEntry;
+ int mX;
+ int mY;
+ int mScrollX;
+ int mScrollY;
+ int mWidth;
+ int mHeight;
+ Matrix mMatrix;
+ float mElevation;
+ float mAlpha = 1.0f;
+
+ 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_SELECTED = 0x00000040;
+ static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
+ static final int FLAGS_CHECKABLE = 0x00000100;
+ static final int FLAGS_CHECKED = 0x00000200;
+ static final int FLAGS_CLICKABLE = 0x00000400;
+ static final int FLAGS_LONG_CLICKABLE = 0x00000800;
+ static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x00001000;
+ static final int FLAGS_ACTIVATED = 0x00002000;
+ static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
+
+ static final int FLAGS_HAS_MATRIX = 0x40000000;
+ static final int FLAGS_HAS_ALPHA = 0x20000000;
+ static final int FLAGS_HAS_ELEVATION = 0x10000000;
+ static final int FLAGS_HAS_SCROLL = 0x08000000;
+ static final int FLAGS_HAS_LARGE_COORDS = 0x04000000;
+ static final int FLAGS_HAS_CONTENT_DESCRIPTION = 0x02000000;
+ static final int FLAGS_HAS_TEXT = 0x01000000;
+ static final int FLAGS_HAS_EXTRAS = 0x00800000;
+ static final int FLAGS_HAS_ID = 0x00400000;
+ static final int FLAGS_HAS_CHILDREN = 0x00200000;
+ static final int FLAGS_ALL_CONTROL = 0xfff00000;
+
+ int mFlags;
+
+ String mClassName;
+ CharSequence mContentDescription;
+
+ ViewNodeText mText;
+ Bundle mExtras;
+
+ ViewNode[] mChildren;
+
+ ViewNode() {
+ }
+
+ ViewNode(Parcel in, PooledStringReader preader, float[] tmpMatrix) {
+ mClassName = preader.readString();
+ mFlags = in.readInt();
+ final int flags = mFlags;
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ mId = in.readInt();
+ if (mId != 0) {
+ mIdEntry = preader.readString();
+ if (mIdEntry != null) {
+ mIdType = preader.readString();
+ mIdPackage = preader.readString();
+ }
+ }
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ mX = in.readInt();
+ mY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ } else {
+ int val = in.readInt();
+ mX = val&0x7fff;
+ mY = (val>>16)&0x7fff;
+ val = in.readInt();
+ mWidth = val&0x7fff;
+ mHeight = (val>>16)&0x7fff;
+ }
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ mScrollX = in.readInt();
+ mScrollY = in.readInt();
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix = new Matrix();
+ in.readFloatArray(tmpMatrix);
+ mMatrix.setValues(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ mElevation = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ mAlpha = in.readFloat();
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
+ mText = new ViewNodeText(in);
+ }
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ mExtras = in.readBundle();
+ }
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
+ final int NCHILDREN = in.readInt();
+ mChildren = new ViewNode[NCHILDREN];
+ for (int i=0; i<NCHILDREN; i++) {
+ mChildren[i] = new ViewNode(in, preader, tmpMatrix);
+ }
+ }
+ }
+
+ int writeToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
+ int flags = mFlags & ~FLAGS_ALL_CONTROL;
+ if (mId != View.NO_ID) {
+ flags |= FLAGS_HAS_ID;
+ }
+ if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
+ || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
+ flags |= FLAGS_HAS_LARGE_COORDS;
+ }
+ if (mScrollX != 0 || mScrollY != 0) {
+ flags |= FLAGS_HAS_SCROLL;
+ }
+ if (mMatrix != null) {
+ flags |= FLAGS_HAS_MATRIX;
+ }
+ if (mElevation != 0) {
+ flags |= FLAGS_HAS_ELEVATION;
+ }
+ if (mAlpha != 1.0f) {
+ flags |= FLAGS_HAS_ALPHA;
+ }
+ if (mContentDescription != null) {
+ flags |= FLAGS_HAS_CONTENT_DESCRIPTION;
+ }
+ if (mText != null) {
+ flags |= FLAGS_HAS_TEXT;
+ }
+ if (mExtras != null) {
+ flags |= FLAGS_HAS_EXTRAS;
+ }
+ if (mChildren != null) {
+ flags |= FLAGS_HAS_CHILDREN;
+ }
+
+ pwriter.writeString(mClassName);
+ out.writeInt(flags);
+ if ((flags&FLAGS_HAS_ID) != 0) {
+ out.writeInt(mId);
+ if (mId != 0) {
+ pwriter.writeString(mIdEntry);
+ if (mIdEntry != null) {
+ pwriter.writeString(mIdType);
+ pwriter.writeString(mIdPackage);
+ }
+ }
+ }
+ if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ } else {
+ out.writeInt((mY<<16) | mX);
+ out.writeInt((mHeight<<16) | mWidth);
+ }
+ if ((flags&FLAGS_HAS_SCROLL) != 0) {
+ out.writeInt(mScrollX);
+ out.writeInt(mScrollY);
+ }
+ if ((flags&FLAGS_HAS_MATRIX) != 0) {
+ mMatrix.getValues(tmpMatrix);
+ out.writeFloatArray(tmpMatrix);
+ }
+ if ((flags&FLAGS_HAS_ELEVATION) != 0) {
+ out.writeFloat(mElevation);
+ }
+ if ((flags&FLAGS_HAS_ALPHA) != 0) {
+ out.writeFloat(mAlpha);
+ }
+ if ((flags&FLAGS_HAS_CONTENT_DESCRIPTION) != 0) {
+ TextUtils.writeToParcel(mContentDescription, out, 0);
+ }
+ if ((flags&FLAGS_HAS_TEXT) != 0) {
+ mText.writeToParcel(out);
+ }
+ if ((flags&FLAGS_HAS_EXTRAS) != 0) {
+ out.writeBundle(mExtras);
+ }
+ int N = 1;
+ if ((flags&FLAGS_HAS_CHILDREN) != 0) {
+ final int NCHILDREN = mChildren.length;
+ out.writeInt(NCHILDREN);
+ for (int i=0; i<NCHILDREN; i++) {
+ N += mChildren[i].writeToParcel(out, pwriter, tmpMatrix);
+ }
+ }
+ return N;
+ }
+
+ /**
+ * 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 transformation that has been applied to this view, such as a translation
+ * or scaling. The returned Matrix object is owned by ViewNode; do not modify it.
+ * Returns null if there is no transformation applied to the view.
+ */
+ public Matrix getTransformation() {
+ return mMatrix;
+ }
+
+ /**
+ * Returns the visual elevation of the view, used for shadowing and other visual
+ * characterstics, as set by {@link ViewStructure#setElevation
+ * ViewStructure.setElevation(float)}.
+ */
+ public float getElevation() {
+ return mElevation;
+ }
+
+ /**
+ * Returns the alpha transformation of the view, used to reduce the overall opacity
+ * of the view's contents, as set by {@link ViewStructure#setAlpha
+ * ViewStructure.setAlpha(float)}.
+ */
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ /**
+ * 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 setTransformation(Matrix matrix) {
+ if (matrix == null) {
+ mNode.mMatrix = null;
+ } else {
+ mNode.mMatrix = new Matrix(matrix);
+ }
+ }
+
+ @Override
+ public void setElevation(float elevation) {
+ mNode.mElevation = elevation;
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ mNode.mAlpha = alpha;
+ }
+
+ @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);
+ }
+ Matrix matrix = node.getTransformation();
+ if (matrix != null) {
+ Log.i(TAG, prefix + " Transformation: " + matrix);
+ }
+ float elevation = node.getElevation();
+ if (elevation != 0) {
+ Log.i(TAG, prefix + " Elevation: " + elevation);
+ }
+ float alpha = node.getAlpha();
+ if (alpha != 0) {
+ Log.i(TAG, prefix + " Alpha: " + elevation);
+ }
+ 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.
+ Log.w(TAG, "Skipping assist structure, waiting too long for async children (have "
+ + mPendingAsyncChildren.size() + " remaining");
+ skipStructure = true;
+ }
+ }
+ int start = out.dataPosition();
+ PooledStringWriter pwriter = new PooledStringWriter(out);
+ float[] tmpMatrix = new float[9];
+ ComponentName.writeToParcel(mActivityComponent, out);
+ final int N = skipStructure ? 0 : mWindowNodes.size();
+ out.writeInt(N);
+ int NV = 0;
+ for (int i=0; i<N; i++) {
+ NV += mWindowNodes.get(i).writeToParcel(out, pwriter, tmpMatrix);
+ }
+ pwriter.finish();
+ Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes, containing "
+ + N + " windows, " + NV + " views");
+ }
+
+ void readContentFromParcel(Parcel in) {
+ PooledStringReader preader = new PooledStringReader(in);
+ float[] tmpMatrix = new float[9];
+ mActivityComponent = ComponentName.readFromParcel(in);
+ final int N = in.readInt();
+ for (int i=0; i<N; i++) {
+ mWindowNodes.add(new WindowNode(in, preader, tmpMatrix));
+ }
+ //dump();
}
public int describeContents() {
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 369b692..24647f38 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -372,13 +372,4 @@
return new UsageEvents[size];
}
};
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- if (mParcel != null) {
- mParcel.recycle();
- mParcel = null;
- }
- }
}
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 7bcc0385..9113426 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -54,6 +54,14 @@
public abstract void reportConfigurationChange(Configuration config, int userId);
/**
+ * Reports that a content provider has been accessed by a foreground app.
+ * @param name The authority of the content provider
+ * @param pkgName The package name of the content provider
+ * @param userId The user in which the content provider was accessed.
+ */
+ public abstract void reportContentProviderUsage(String name, String pkgName, int userId);
+
+ /**
* Prepares the UsageStatsService for shutdown.
*/
public abstract void prepareShutdown();
@@ -69,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.
*/
@@ -82,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/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 67d9de5..eaf20d8 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -152,7 +152,6 @@
*/
public void stopAdvertising(final AdvertiseCallback callback) {
synchronized (mLeAdvertisers) {
- BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
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/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 057001c..6ede29b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -48,6 +48,7 @@
import dalvik.system.CloseGuard;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
import java.io.File;
@@ -57,6 +58,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -1591,7 +1593,11 @@
@NonNull ContentObserver observer) {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(observer, "observer");
- registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId());
+ registerContentObserver(
+ ContentProvider.getUriWithoutUserId(uri),
+ notifyForDescendents,
+ observer,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/** @hide - designated user version */
@@ -1657,7 +1663,11 @@
public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
boolean syncToNetwork) {
Preconditions.checkNotNull(uri, "uri");
- notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId());
+ notifyChange(
+ ContentProvider.getUriWithoutUserId(uri),
+ observer,
+ syncToNetwork,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
}
/**
@@ -1936,6 +1946,19 @@
}
/**
+ * @hide
+ * Returns the package names of syncadapters that match a given user and authority.
+ */
+ public static String[] getSyncAdapterPackagesForAuthorityAsUser(String authority,
+ int userId) {
+ try {
+ return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ } catch (RemoteException e) {
+ }
+ return ArrayUtils.emptyArray(String.class);
+ }
+
+ /**
* Check if the provider should be synced when a network tickle is received
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 9998f08..8b471a0 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -143,6 +143,8 @@
SyncAdapterType[] getSyncAdapterTypes();
SyncAdapterType[] getSyncAdapterTypesAsUser(int userId);
+ String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId);
+
/**
* Returns true if there is currently a operation for the given account/authority or service
* actively being processed.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5190037..b1d80f0 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1020,6 +1020,11 @@
* <p>Note: this Intent <strong>cannot</strong> be used to call emergency
* numbers. Applications can <strong>dial</strong> emergency numbers using
* {@link #ACTION_DIAL}, however.
+ *
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC}
+ * and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
+ * permission which is not granted, then atempting to use this action will
+ * result in a {@link java.lang.SecurityException}.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CALL = "android.intent.action.CALL";
@@ -3779,6 +3784,9 @@
/** {@hide} */
public static final String EXTRA_REASON = "android.intent.extra.REASON";
+ /** {@hide} */
+ public static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
+
/**
* Optional {@link android.app.PendingIntent} extra used to deliver the result of the SIM
* activation request.
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 08c5236..19329ce 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -16,7 +16,6 @@
package android.content;
-import android.content.pm.PackageParser;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -519,7 +518,8 @@
}
/**
- * Return if this filter handle all HTTP or HTTPS data URI or not.
+ * Return if this filter handle all HTTP or HTTPS data URI or not. This is the
+ * core check for whether a given activity qualifies as a "browser".
*
* @return True if the filter handle all HTTP or HTTPS data URI. False otherwise.
*
@@ -534,24 +534,60 @@
*/
public final boolean handleAllWebDataURI() {
return hasCategory(Intent.CATEGORY_APP_BROWSER) ||
- (hasWebDataURI() && countDataAuthorities() == 0);
+ (handlesWebUris(false) && countDataAuthorities() == 0);
}
/**
- * Return if this filter has any HTTP or HTTPS data URI or not.
+ * Return if this filter handles HTTP or HTTPS data URIs.
*
- * @return True if the filter has any HTTP or HTTPS data URI. False otherwise.
+ * @return True if the filter handles ACTION_VIEW/CATEGORY_BROWSABLE,
+ * has at least one HTTP or HTTPS data URI pattern defined, and optionally
+ * does not define any non-http/https data URI patterns.
*
* This will check if if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
* the Intent category is {@link android.content.Intent#CATEGORY_BROWSABLE} and the Intent
* data scheme is "http" or "https".
*
+ * @param onlyWebSchemes When true, requires that the intent filter declare
+ * that it handles *only* http: or https: schemes. This is a requirement for
+ * the intent filter's domain linkage being verifiable.
* @hide
*/
- public final boolean hasWebDataURI() {
- return hasAction(Intent.ACTION_VIEW) &&
- hasCategory(Intent.CATEGORY_BROWSABLE) &&
- (hasDataScheme(SCHEME_HTTP) || hasDataScheme(SCHEME_HTTPS));
+ public final boolean handlesWebUris(boolean onlyWebSchemes) {
+ // Require ACTION_VIEW, CATEGORY_BROWSEABLE, and at least one scheme
+ if (!hasAction(Intent.ACTION_VIEW)
+ || !hasCategory(Intent.CATEGORY_BROWSABLE)
+ || mDataSchemes == null
+ || mDataSchemes.size() == 0) {
+ return false;
+ }
+
+ // Now allow only the schemes "http" and "https"
+ final int N = mDataSchemes.size();
+ for (int i = 0; i < N; i++) {
+ final String scheme = mDataSchemes.get(i);
+ final boolean isWebScheme =
+ SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme);
+ if (onlyWebSchemes) {
+ // If we're specifically trying to ensure that there are no non-web schemes
+ // declared in this filter, then if we ever see a non-http/https scheme then
+ // we know it's a failure.
+ if (!isWebScheme) {
+ return false;
+ }
+ } else {
+ // If we see any http/https scheme declaration in this case then the
+ // filter matches what we're looking for.
+ if (isWebScheme) {
+ return true;
+ }
+ }
+ }
+
+ // We get here if:
+ // 1) onlyWebSchemes and no non-web schemes were found, i.e success; or
+ // 2) !onlyWebSchemes and no http/https schemes were found, i.e. failure.
+ return onlyWebSchemes;
}
/**
@@ -568,7 +604,7 @@
* @hide
*/
public final boolean needsVerification() {
- return hasWebDataURI() && getAutoVerify();
+ return getAutoVerify() && handlesWebUris(true);
}
/**
@@ -1480,7 +1516,11 @@
* Write the contents of the IntentFilter as an XML stream.
*/
public void writeToXml(XmlSerializer serializer) throws IOException {
- serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(getAutoVerify()));
+
+ if (getAutoVerify()) {
+ serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(true));
+ }
+
int N = countActions();
for (int i=0; i<N; i++) {
serializer.startTag(null, ACTION_STR);
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index 8bb3ee7..6704b75 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -20,12 +20,19 @@
import android.content.pm.XmlSerializerAndParser;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.util.ArrayMap;
import android.util.AttributeSet;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
/**
* A cache of services that export the {@link android.content.ISyncAdapter} interface.
@@ -39,6 +46,10 @@
private static final String ATTRIBUTES_NAME = "sync-adapter";
private static final MySerializer sSerializer = new MySerializer();
+ @GuardedBy("mServicesLock")
+ private SparseArray<ArrayMap<String,String[]>> mAuthorityToSyncAdapters
+ = new SparseArray<>();
+
public SyncAdaptersCache(Context context) {
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer);
}
@@ -76,6 +87,57 @@
}
}
+ @Override
+ protected void onServicesChangedLocked(int userId) {
+ synchronized (mServicesLock) {
+ ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId);
+ if (adapterMap != null) {
+ adapterMap.clear();
+ }
+ }
+
+ super.onServicesChangedLocked(userId);
+ }
+
+ public String[] getSyncAdapterPackagesForAuthority(String authority, int userId) {
+ synchronized (mServicesLock) {
+ ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId);
+ if (adapterMap == null) {
+ adapterMap = new ArrayMap<>();
+ mAuthorityToSyncAdapters.put(userId, adapterMap);
+ }
+ // If the mapping exists, return it
+ if (adapterMap.containsKey(authority)) {
+ return adapterMap.get(authority);
+ }
+ // Create the mapping and cache it
+ String[] syncAdapterPackages;
+ final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos;
+ serviceInfos = getAllServices(userId);
+ ArrayList<String> packages = new ArrayList<>();
+ for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) {
+ if (authority.equals(serviceInfo.type.authority)
+ && serviceInfo.componentName != null) {
+ packages.add(serviceInfo.componentName.getPackageName());
+ }
+ }
+ syncAdapterPackages = new String[packages.size()];
+ packages.toArray(syncAdapterPackages);
+ adapterMap.put(authority, syncAdapterPackages);
+
+ return syncAdapterPackages;
+ }
+ }
+
+ @Override
+ protected void onUserRemoved(int userId) {
+ synchronized (mServicesLock) {
+ mAuthorityToSyncAdapters.remove(userId);
+ }
+
+ super.onUserRemoved(userId);
+ }
+
static class MySerializer implements XmlSerializerAndParser<SyncAdapterType> {
public void writeAsXml(SyncAdapterType item, XmlSerializer out) throws IOException {
out.attribute(null, "authority", item.authority);
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9fb6f4d..6feb860 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -962,6 +962,13 @@
/**
* @hide
*/
+ public boolean isPrivilegedApp() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+ }
+
+ /**
+ * @hide
+ */
public boolean isUpdatedSystemApp() {
return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0c07bc3..2b83d86 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -101,11 +101,15 @@
void revokeRuntimePermission(String packageName, String permissionName, int userId);
+ void resetRuntimePermissions();
+
int getPermissionFlags(String permissionName, String packageName, int userId);
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 +286,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 +307,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 +371,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 +379,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 +387,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 +397,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 +411,7 @@
FeatureInfo[] getSystemAvailableFeatures();
boolean hasSystemFeature(String name);
-
+
void enterSafeMode();
boolean isSafeMode();
void systemReady();
@@ -494,4 +502,8 @@
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
+
+ int getMountExternalMode(int uid);
+
+ void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, 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/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
new file mode 100644
index 0000000..dbaba49
--- /dev/null
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -0,0 +1,84 @@
+/*
+ * 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.content.pm;
+
+import android.annotation.NonNull;
+
+/**
+ * Package manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class PackageManagerInternal {
+
+ /**
+ * Provider for package names.
+ */
+ public interface PackagesProvider {
+
+ /**
+ * Gets the packages for a given user.
+ * @param userId The user id.
+ * @return The package names.
+ */
+ public String[] getPackages(int userId);
+ }
+
+ /**
+ * Sets the location provider packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setLocationPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the input method packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setImePackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the voice interaction packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the SMS packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Sets the dialer packages provider.
+ * @param provider The packages provider.
+ */
+ public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
+
+ /**
+ * Requests granting of the default permissions to the current default SMS app.
+ * @param packageName The default SMS package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId);
+
+ /**
+ * Requests granting of the default permissions to the current default dialer app.
+ * @param packageName The default dialer package name.
+ * @param userId The user for which to grant the permissions.
+ */
+ public abstract void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId);
+}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 287e0c5..faf71ee 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4508,6 +4508,13 @@
/**
* @hide
*/
+ public boolean isPrivilegedApp() {
+ return applicationInfo.isPrivilegedApp();
+ }
+
+ /**
+ * @hide
+ */
public boolean isUpdatedSystemApp() {
return applicationInfo.isUpdatedSystemApp();
}
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/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 0bd2a3b..b293e2a 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -84,7 +84,7 @@
private final String mAttributesName;
private final XmlSerializerAndParser<V> mSerializerAndParser;
- private final Object mServicesLock = new Object();
+ protected final Object mServicesLock = new Object();
@GuardedBy("mServicesLock")
private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2);
@@ -232,6 +232,7 @@
synchronized (mServicesLock) {
final UserServices<V> user = findOrCreateUserLocked(userId);
user.services = null;
+ onServicesChangedLocked(userId);
}
}
@@ -489,11 +490,16 @@
}
}
if (changed) {
+ onServicesChangedLocked(userId);
writePersistentServicesLocked(user, userId);
}
}
}
+ protected void onServicesChangedLocked(int userId) {
+ // Feel free to override
+ }
+
/**
* Returns true if the list of changed uids is null (wildcard) or the specified uid
* is contained in the list of changed uids.
@@ -687,7 +693,9 @@
@VisibleForTesting
protected void onUserRemoved(int userId) {
- mUserServices.remove(userId);
+ synchronized (mServicesLock) {
+ mUserServices.remove(userId);
+ }
}
@VisibleForTesting
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 649fdb4..7bab35c 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -45,7 +45,7 @@
* {@link #providerInfo} will be non-null.
*/
public ActivityInfo activityInfo;
-
+
/**
* The service that corresponds to this resolution match, if this resolution
* is for a service. Exactly one of {@link #activityInfo},
@@ -64,21 +64,21 @@
* The IntentFilter that was matched for this ResolveInfo.
*/
public IntentFilter filter;
-
+
/**
* The declared priority of this match. Comes from the "priority"
* attribute or, if not set, defaults to 0. Higher values are a higher
* priority.
*/
public int priority;
-
+
/**
* Order of result according to the user's preference. If the user
* has not set a preference for this result, the value is 0; higher
* values are a higher priority.
*/
public int preferredOrder;
-
+
/**
* The system's evaluation of how well the activity matches the
* IntentFilter. This is a match constant, a combination of
@@ -86,7 +86,7 @@
* and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}.
*/
public int match;
-
+
/**
* Only set when returned by
* {@link PackageManager#queryIntentActivityOptions}, this tells you
@@ -94,29 +94,30 @@
* first in the list, < 0 means it came from the generic Intent query.
*/
public int specificIndex = -1;
-
+
/**
* This filter has specified the Intent.CATEGORY_DEFAULT, meaning it
* would like to be considered a default action that the user can
* perform on this data.
*/
public boolean isDefault;
-
+
/**
* A string resource identifier (in the package's resources) of this
* match's label. From the "label" attribute or, if not set, 0.
*/
public int labelRes;
-
+
/**
* The actual string retrieve from <var>labelRes</var> or null if none
* was provided.
*/
public CharSequence nonLocalizedLabel;
-
+
/**
* A drawable resource identifier (in the package's resources) of this
- * match's icon. From the "icon" attribute or, if not set, 0.
+ * match's icon. From the "icon" attribute or, if not set, 0. It is
+ * set only if the icon can be obtained by resource id alone.
*/
public int icon;
@@ -134,11 +135,21 @@
public int targetUserId;
/**
+ * Set to true if the icon cannot be obtained by resource ids alone.
+ * It is set to true for ResolveInfos from the managed profile: They need to
+ * have their icon badged, so it cannot be obtained by resource ids alone.
* @hide
*/
public boolean noResourceId;
/**
+ * Same as {@link #icon} but it will always correspond to "icon" attribute
+ * regardless of {@link #noResourceId} value.
+ * @hide
+ */
+ public int iconResourceId;
+
+ /**
* @hide Target comes from system process?
*/
public boolean system;
@@ -159,10 +170,10 @@
* Retrieve the current textual label associated with this resolution. This
* will call back on the given PackageManager to load the label from
* the application.
- *
+ *
* @param pm A PackageManager from which the label can be loaded; usually
* the PackageManager from which you originally retrieved this item.
- *
+ *
* @return Returns a CharSequence containing the resolutions's label. If the
* item does not have a label, its name is returned.
*/
@@ -191,33 +202,30 @@
if (data != null) data = data.toString().trim();
return data;
}
-
+
/**
* Retrieve the current graphical icon associated with this resolution. This
* will call back on the given PackageManager to load the icon from
* the application.
- *
+ *
* @param pm A PackageManager from which the icon can be loaded; usually
* the PackageManager from which you originally retrieved this item.
- *
+ *
* @return Returns a Drawable containing the resolution's icon. If the
* item does not have an icon, the default activity icon is returned.
*/
public Drawable loadIcon(PackageManager pm) {
- Drawable dr;
- if (resolvePackageName != null && icon != 0) {
- dr = pm.getDrawable(resolvePackageName, icon, null);
- if (dr != null) {
- return dr;
- }
+ Drawable dr = null;
+ if (resolvePackageName != null && iconResourceId != 0) {
+ dr = pm.getDrawable(resolvePackageName, iconResourceId, null);
}
ComponentInfo ci = getComponentInfo();
- ApplicationInfo ai = ci.applicationInfo;
- if (icon != 0) {
- dr = pm.getDrawable(ci.packageName, icon, ai);
- if (dr != null) {
- return dr;
- }
+ if (dr == null && iconResourceId != 0) {
+ ApplicationInfo ai = ci.applicationInfo;
+ dr = pm.getDrawable(ci.packageName, iconResourceId, ai);
+ }
+ if (dr != null) {
+ return pm.getUserBadgedIcon(dr, new UserHandle(UserHandle.myUserId()));
}
return ci.loadIcon(pm);
}
@@ -231,7 +239,7 @@
* @return The icon associated with this match.
*/
final int getIconResourceInternal() {
- if (icon != 0) return icon;
+ if (iconResourceId != 0) return iconResourceId;
final ComponentInfo ci = getComponentInfo();
if (ci != null) {
return ci.getIconResource();
@@ -298,6 +306,8 @@
nonLocalizedLabel = orig.nonLocalizedLabel;
icon = orig.icon;
resolvePackageName = orig.resolvePackageName;
+ noResourceId = orig.noResourceId;
+ iconResourceId = orig.iconResourceId;
system = orig.system;
targetUserId = orig.targetUserId;
handleAllWebDataURI = orig.handleAllWebDataURI;
@@ -362,6 +372,7 @@
dest.writeInt(targetUserId);
dest.writeInt(system ? 1 : 0);
dest.writeInt(noResourceId ? 1 : 0);
+ dest.writeInt(iconResourceId);
dest.writeInt(handleAllWebDataURI ? 1 : 0);
}
@@ -408,9 +419,10 @@
targetUserId = source.readInt();
system = source.readInt() != 0;
noResourceId = source.readInt() != 0;
+ iconResourceId = source.readInt();
handleAllWebDataURI = source.readInt() != 0;
}
-
+
public static class DisplayNameComparator
implements Comparator<ResolveInfo> {
public DisplayNameComparator(PackageManager pm) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 27d14b3..c47498d 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 =
@@ -2752,35 +2738,13 @@
/**
* <p>The maximum number of frames that can occur after a request
* (different than the previous) has been submitted, and before the
- * result's state becomes synchronized (by setting
- * android.sync.frameNumber to a non-negative value).</p>
+ * result's state becomes synchronized.</p>
* <p>This defines the maximum distance (in number of metadata results),
- * between android.sync.frameNumber and the equivalent
- * frame number for that result.</p>
+ * between the frame number of the request that has new controls to apply
+ * and the frame number of the result that has all the controls applied.</p>
* <p>In other words this acts as an upper boundary for how many frames
* must occur before the camera device knows for a fact that the new
* submitted camera settings have been applied in outgoing frames.</p>
- * <p>For example if the distance was 2,</p>
- * <pre><code>initial request = X (repeating)
- * request1 = X
- * request2 = Y
- * request3 = Y
- * request4 = Y
- *
- * where requestN has frameNumber N, and the first of the repeating
- * initial request's has frameNumber F (and F < 1).
- *
- * initial result = X' + { android.sync.frameNumber == F }
- * result1 = X' + { android.sync.frameNumber == F }
- * result2 = X' + { android.sync.frameNumber == CONVERGING }
- * result3 = X' + { android.sync.frameNumber == CONVERGING }
- * result4 = X' + { android.sync.frameNumber == 2 }
- *
- * where resultN has frameNumber N.
- * </code></pre>
- * <p>Since <code>result4</code> has a <code>frameNumber == 4</code> and
- * <code>android.sync.frameNumber == 2</code>, the distance is clearly
- * <code>4 - 2 = 2</code>.</p>
* <p><b>Units</b>: Frame counts</p>
* <p><b>Possible values:</b>
* <ul>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 006030c..639c8b1 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -236,13 +236,16 @@
* {@link CameraCaptureSession.StateCallback}'s
* {@link CameraCaptureSession.StateCallback#onConfigured} callback will be called.</p>
*
- * <p>If a prior CameraCaptureSession already exists when a new one is created, the previous
- * session is closed. Any in-progress capture requests made on the prior session will be
- * completed before the new session is configured and is able to start capturing its own
- * requests. To minimize the transition time, the {@link CameraCaptureSession#abortCaptures}
- * call can be used to discard the remaining requests for the prior capture session before a new
- * one is created. Note that once the new session is created, the old one can no longer have its
- * captures aborted.</p>
+ * <p>If a prior CameraCaptureSession already exists when this method is called, the previous
+ * session will no longer be able to accept new capture requests and will be closed. Any
+ * in-progress capture requests made on the prior session will be completed before it's closed.
+ * {@link CameraCaptureSession.StateListener#onConfigured} for the new session may be invoked
+ * before {@link CameraCaptureSession.StateListener#onClosed} is invoked for the prior
+ * session. Once the new session is {@link CameraCaptureSession.StateListener#onConfigured
+ * configured}, it is able to start capturing its own requests. To minimize the transition time,
+ * the {@link CameraCaptureSession#abortCaptures} call can be used to discard the remaining
+ * requests for the prior capture session before a new one is created. Note that once the new
+ * session is created, the old one can no longer have its captures aborted.</p>
*
* <p>Using larger resolution outputs, or more outputs, can result in slower
* output rate from the device.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index f8db6d9..e8dbc5b 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
*/
@@ -667,7 +662,7 @@
* {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }.
* The fps range can be controlled via {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}.</p>
* <p>In this capability, the camera device will override aeMode, awbMode, and afMode to
- * ON, ON, and CONTINUOUS_VIDEO, respectively. All post-processing block mode
+ * ON, AUTO, and CONTINUOUS_VIDEO, respectively. All post-processing block mode
* controls will be overridden to be FAST. Therefore, no manual control of capture
* and post-processing parameters is possible. All other controls operate the
* same as when {@link CaptureRequest#CONTROL_MODE android.control.mode} == AUTO. This means that all other
@@ -954,21 +949,12 @@
*/
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
//
/**
* <p>Every frame has the requests immediately applied.</p>
- * <p>Furthermore for all results,
- * <code>android.sync.frameNumber == {@link android.hardware.camera2.CaptureResult#getFrameNumber }</code></p>
* <p>Changing controls over multiple requests one after another will
* produce results that have those controls applied atomically
* each frame.</p>
@@ -1666,9 +1652,9 @@
* <p>Enabling this disables control.aeMode, control.awbMode and
* control.afMode controls; the camera device will ignore
* those settings while USE_SCENE_MODE is active (except for
- * FACE_PRIORITY scene mode). Other control entries are still
- * active. This setting can only be used if scene mode is
- * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
+ * FACE_PRIORITY scene mode). Other control entries are still active.
+ * This setting can only be used if scene mode is supported (i.e.
+ * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
* contain some modes other than DISABLED).</p>
*
* @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
@@ -1940,6 +1926,40 @@
*/
public static final int CONTROL_SCENE_MODE_HDR = 18;
+ /**
+ * <p>Same as FACE_PRIORITY scene mode, except that the camera
+ * device will choose higher sensivity values ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity})
+ * under low light conditions.</p>
+ * <p>The camera device may be tuned to expose the images in a reduced
+ * sensitivity range to produce the best quality images. For example,
+ * if the {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} gives range of [100, 1600],
+ * the camera device auto-exposure routine tuning process may limit the actual
+ * exposure sensivity range to [100, 1200] to ensure that the noise level isn't
+ * exessive to compromise the image quality. Under this situation, the image under
+ * low light may be under-exposed when the sensor max exposure time (bounded by the
+ * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of the
+ * ON_* modes) and effecitve max sensitivity are reached. This scene mode allows the
+ * camera device auto-exposure routine to increase the sensitivity up to the max
+ * sensitivity specified by {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} when the scene is too
+ * dark and the max exposure time is reached. The captured images may be noisier
+ * compared with the images captured in normal FACE_PRIORITY mode, therefore, it is
+ * recommended that the application only use this scene mode when it is capable of
+ * reducing the noise level of the captured images.</p>
+ * <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
+ * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+ * remain active when FACE_PRIORITY_LOW_LIGHT is set.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_MODE
+ * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE
+ * @see CaptureRequest#CONTROL_AF_MODE
+ * @see CaptureRequest#CONTROL_AWB_MODE
+ * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
+ * @see CaptureRequest#SENSOR_SENSITIVITY
+ * @see CaptureRequest#CONTROL_SCENE_MODE
+ * @hide
+ */
+ public static final int CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19;
+
//
// Enumeration values for CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index bc625dd..33cc962 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 =
@@ -1062,6 +1062,15 @@
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -1075,6 +1084,7 @@
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1179,6 +1189,12 @@
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1187,6 +1203,7 @@
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
@@ -1448,9 +1465,9 @@
* <p>Scene modes are custom camera modes optimized for a certain set of conditions and
* capture settings.</p>
* <p>This is the mode that that is active when
- * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
- * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
- * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+ * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will
+ * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+ * while in use.</p>
* <p>The interpretation and implementation of these scene modes is left
* to the implementor of the camera device. Their behavior will not be
* consistent across all devices, and any given device may only implement
@@ -1759,11 +1776,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 da216aa..9dee045 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -779,6 +779,15 @@
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -792,6 +801,7 @@
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1139,6 +1149,12 @@
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1147,6 +1163,7 @@
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
@@ -1960,9 +1977,9 @@
* <p>Scene modes are custom camera modes optimized for a certain set of conditions and
* capture settings.</p>
* <p>This is the mode that that is active when
- * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
- * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
- * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+ * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will
+ * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+ * while in use.</p>
* <p>The interpretation and implementation of these scene modes is left
* to the implementor of the camera device. Their behavior will not be
* consistent across all devices, and any given device may only implement
@@ -2314,11 +2331,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/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index f928a555..bc80fc1 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -630,8 +630,6 @@
holder.width = surfaceSize.getWidth();
holder.height = surfaceSize.getHeight();
if (LegacyCameraDevice.needsConversion(s)) {
- // Always override to YV12 output for YUV surface formats.
- LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12);
mConversionSurfaces.add(holder);
} else {
mSurfaces.add(holder);
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/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 0484806..f596c93 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -26,7 +26,7 @@
*/
interface IFingerprintService {
// Authenticate the given sessionId with a fingerprint
- void authenticate(IBinder token, long sessionId, int groupId,
+ void authenticate(IBinder token, long sessionId, int userId,
IFingerprintServiceReceiver receiver, int flags, String opPackageName);
// Cancel authentication for the given sessionId
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index f965f54..8bc2876 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -165,6 +165,14 @@
}
/**
+ * @hide
+ */
+ @Override
+ public boolean isInExtractedMode() {
+ return true;
+ }
+
+ /**
* {@inheritDoc}
* @hide
*/
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index ae74b9a..ff7a300 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1819,7 +1819,18 @@
}
return false;
}
-
+
+ /**
+ * @return {#link ExtractEditText} if it is considered to be visible and active. Otherwise
+ * {@code null} is returned.
+ */
+ private ExtractEditText getExtractEditTextIfVisible() {
+ if (!isExtractViewShown() || !isInputViewShown()) {
+ return null;
+ }
+ return mExtractEditText;
+ }
+
/**
* Override this to intercept key down events before they are processed by the
* application. If you return true, the application will not
@@ -1835,6 +1846,10 @@
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ final ExtractEditText eet = getExtractEditTextIfVisible();
+ if (eet != null && eet.handleBackInTextActionModeIfNeeded(event)) {
+ return true;
+ }
if (handleBack(false)) {
event.startTracking();
return true;
@@ -1882,11 +1897,15 @@
* them to perform navigation in the underlying application.
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isTracking()
- && !event.isCanceled()) {
- return handleBack(true);
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ final ExtractEditText eet = getExtractEditTextIfVisible();
+ if (eet != null && eet.handleBackInTextActionModeIfNeeded(event)) {
+ return true;
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ return handleBack(true);
+ }
}
-
return doMovementKey(keyCode, event, MOVEMENT_UP);
}
@@ -1952,10 +1971,10 @@
}
onExtractedCursorMovement(dx, dy);
}
-
+
boolean doMovementKey(int keyCode, KeyEvent event, int count) {
- final ExtractEditText eet = mExtractEditText;
- if (isExtractViewShown() && isInputViewShown() && eet != null) {
+ final ExtractEditText eet = getExtractEditTextIfVisible();
+ if (eet != null) {
// If we are in fullscreen mode, the cursor will move around
// the extract edit text, but should NOT cause focus to move
// to other fields.
@@ -2006,7 +2025,7 @@
return true;
}
}
-
+
return false;
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a2ca41c..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,
@@ -2461,18 +2473,28 @@
* Intent to reserve the network or it will be released shortly after the Intent
* is processed.
* <p>
- * If there is already an request for this Intent registered (with the equality of
+ * If there is already a request for this Intent registered (with the equality of
* two Intents defined by {@link Intent#filterEquals}), then it will be removed and
* replaced by this one, effectively releasing the previous {@link NetworkRequest}.
* <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);
@@ -2521,6 +2543,44 @@
}
/**
+ * Registers a PendingIntent to be sent when a network is available which satisfies the given
+ * {@link NetworkRequest}.
+ *
+ * This function behaves identically to the version that takes a NetworkCallback, but instead
+ * of {@link NetworkCallback} a {@link PendingIntent} is used. This means
+ * the request may outlive the calling application and get called back when a suitable
+ * network is found.
+ * <p>
+ * The operation is an Intent broadcast that goes to a broadcast receiver that
+ * you registered with {@link Context#registerReceiver} or through the
+ * <receiver> tag in an AndroidManifest.xml file
+ * <p>
+ * The operation Intent is delivered with two extras, a {@link Network} typed
+ * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
+ * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
+ * the original requests parameters.
+ * <p>
+ * If there is already a request for this Intent registered (with the equality of
+ * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
+ * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
+ * <p>
+ * The request may be released normally by calling
+ * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_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.
+ */
+ public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
+ checkPendingIntent(operation);
+ try {
+ mService.pendingListenForNetwork(request.networkCapabilities, operation);
+ } catch (RemoteException e) {}
+ }
+
+ /**
* Requests bandwidth update for a given {@link Network} and returns whether the update request
* is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
* network connection for updated bandwidth information. The caller will be notified via
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 31aedad..cfd5bf1 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -517,7 +517,7 @@
* Note that Http Proxies are only a hint - the system recommends their use, but it does
* not enforce it and applications may ignore them.
*
- * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+ * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
* @hide
*/
public void setHttpProxy(ProxyInfo proxy) {
@@ -774,6 +774,43 @@
}
/**
+ * Evaluate whether the {@link InetAddress} is considered reachable.
+ *
+ * @return {@code true} if the given {@link InetAddress} is considered reachable,
+ * {@code false} otherwise.
+ * @hide
+ */
+ public boolean isReachable(InetAddress ip) {
+ final List<RouteInfo> allRoutes = getAllRoutes();
+ // If we don't have a route to this IP address, it's not reachable.
+ final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
+ if (bestRoute == null) {
+ return false;
+ }
+
+ // TODO: better source address evaluation for destination addresses.
+
+ if (ip instanceof Inet4Address) {
+ // For IPv4, it suffices for now to simply have any address.
+ return hasIPv4Address();
+ } else if (ip instanceof Inet6Address) {
+ if (ip.isLinkLocalAddress()) {
+ // For now, just make sure link-local destinations have
+ // scopedIds set, since transmits will generally fail otherwise.
+ // TODO: verify it matches the ifindex of one of the interfaces.
+ return (((Inet6Address)ip).getScopeId() != 0);
+ } else {
+ // For non-link-local destinations check that either the best route
+ // is directly connected or that some global preferred address exists.
+ // TODO: reconsider all cases (disconnected ULA networks, ...).
+ return (!bestRoute.hasGateway() || hasGlobalIPv6Address());
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Compares this {@code LinkProperties} interface name against the target
*
* @param target LinkProperties to compare.
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 d165240..7fda30a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -65,7 +65,7 @@
* A constant indicating a window wake lock timer.
*/
public static final int WAKE_TYPE_WINDOW = 2;
-
+
/**
* A constant indicating a sensor timer.
*/
@@ -142,6 +142,11 @@
public static final int CAMERA_TURNED_ON = 17;
/**
+ * A constant indicating a draw wake lock timer.
+ */
+ public static final int WAKE_TYPE_DRAW = 18;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -1165,25 +1170,23 @@
public static final int EVENT_USER_FOREGROUND = 0x0008;
// Event for connectivity changed.
public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
- // Event for significant motion taking us out of idle mode.
- public static final int EVENT_SIGNIFICANT_MOTION = 0x000a;
// Event for becoming active taking us out of idle mode.
- public static final int EVENT_ACTIVE = 0x000b;
+ public static final int EVENT_ACTIVE = 0x000a;
// Event for a package being installed.
- public static final int EVENT_PACKAGE_INSTALLED = 0x000c;
+ public static final int EVENT_PACKAGE_INSTALLED = 0x000b;
// Event for a package being uninstalled.
- public static final int EVENT_PACKAGE_UNINSTALLED = 0x000d;
+ public static final int EVENT_PACKAGE_UNINSTALLED = 0x000c;
// Event for a package being uninstalled.
- public static final int EVENT_ALARM = 0x000e;
+ public static final int EVENT_ALARM = 0x000d;
// Record that we have decided we need to collect new stats data.
- public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000f;
+ public static final int EVENT_COLLECT_EXTERNAL_STATS = 0x000e;
// Event for a package becoming inactive due to being unused for a period of time.
- public static final int EVENT_PACKAGE_INACTIVE = 0x0010;
+ public static final int EVENT_PACKAGE_INACTIVE = 0x000f;
// Event for a package becoming active due to an interaction.
- public static final int EVENT_PACKAGE_ACTIVE = 0x0011;
+ public static final int EVENT_PACKAGE_ACTIVE = 0x0010;
// Number of event types.
- public static final int EVENT_COUNT = 0x0012;
+ public static final int EVENT_COUNT = 0x0011;
// Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@@ -1840,12 +1843,12 @@
public static final String[] HISTORY_EVENT_NAMES = new String[] {
"null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn",
- "motion", "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active"
+ "active", "pkginst", "pkgunin", "alarm", "stats", "inactive", "active"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
"Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn",
- "Esm", "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa"
+ "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa"
};
/**
@@ -3836,6 +3839,7 @@
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
= u.getWakelockStats();
long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
+ long totalDrawWakelock = 0;
int countWakelock = 0;
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
final Uid.Wakelock wl = wakelocks.valueAt(iw);
@@ -3850,19 +3854,21 @@
"partial", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
"window", which, linePrefix);
- if (true || !linePrefix.equals(": ")) {
- sb.append(" realtime");
- // Only print out wake locks that were held
- pw.println(sb.toString());
- uidActivity = true;
- countWakelock++;
- }
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
+ "draw", which, linePrefix);
+ sb.append(" realtime");
+ pw.println(sb.toString());
+ uidActivity = true;
+ countWakelock++;
+
totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
rawRealtime, which);
totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
rawRealtime, which);
totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
rawRealtime, which);
+ totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
+ rawRealtime, which);
}
if (countWakelock > 1) {
if (totalFullWakelock != 0 || totalPartialWakelock != 0
@@ -3892,6 +3898,14 @@
formatTimeMs(sb, totalWindowWakelock);
sb.append("window");
}
+ if (totalDrawWakelock != 0) {
+ if (needComma) {
+ sb.append(",");
+ }
+ needComma = true;
+ formatTimeMs(sb, totalDrawWakelock);
+ sb.append("draw");
+ }
sb.append(" realtime");
pw.println(sb.toString());
}
@@ -4017,8 +4031,10 @@
if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
sb.setLength(0);
sb.append(prefix);
- sb.append(" Total cpu time: ");
- formatTimeMs(sb, (userCpuTimeUs + systemCpuTimeUs) / 1000);
+ sb.append(" Total cpu time: u=");
+ formatTimeMs(sb, userCpuTimeUs / 1000);
+ sb.append("s=");
+ formatTimeMs(sb, systemCpuTimeUs / 1000);
pw.println(sb.toString());
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 50eed3e..b2ced7f 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -622,7 +622,7 @@
/**
* M comes after L.
*/
- public static final int MNC = CUR_DEVELOPMENT;
+ public static final int MNC = 23;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/DeadObjectException.java b/core/java/android/os/DeadObjectException.java
index 94c5387..e06b0f9 100644
--- a/core/java/android/os/DeadObjectException.java
+++ b/core/java/android/os/DeadObjectException.java
@@ -25,4 +25,8 @@
public DeadObjectException() {
super();
}
+
+ public DeadObjectException(String message) {
+ super(message);
+ }
}
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/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index 268295d..fe4aa13 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -28,4 +28,5 @@
int[] getAppIdTempWhitelist();
boolean isPowerSaveWhitelistApp(String name);
void addPowerSaveTempWhitelistApp(String name, long duration, int userId);
+ void exitIdle(String reason);
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index dbb5146..7234e98 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -635,14 +635,18 @@
if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
argsForZygote.add("--enable-jit");
}
- if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) {
- argsForZygote.add("--generate-cfi");
+ if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
+ argsForZygote.add("--generate-debug-info");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+ argsForZygote.add("--mount-external-read");
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+ argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
@@ -802,7 +806,12 @@
* @hide
*/
public static final boolean isIsolated() {
- int uid = UserHandle.getAppId(myUid());
+ return isIsolated(myUid());
+ }
+
+ /** {@hide} */
+ public static final boolean isIsolated(int uid) {
+ uid = UserHandle.getAppId(uid);
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
}
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..6384af3 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -449,6 +449,25 @@
public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
/**
+ * Allows apps in the parent profile to handle web links from the managed profile.
+ *
+ * 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_PROFILE_APP_LINKING
+ = "allow_parent_profile_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/IMountService.java b/core/java/android/os/storage/IMountService.java
index e55ae99..84a879c 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1177,6 +1177,21 @@
_data.recycle();
}
}
+
+ @Override
+ public void remountUid(int uid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(uid);
+ mRemote.transact(Stub.TRANSACTION_remountUid, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
}
private static final String DESCRIPTOR = "IMountService";
@@ -1292,6 +1307,8 @@
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
+ static final int TRANSACTION_remountUid = IBinder.FIRST_CALL_TRANSACTION + 61;
+
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1845,6 +1862,13 @@
reply.writeNoException();
return true;
}
+ case TRANSACTION_remountUid: {
+ data.enforceInterface(DESCRIPTOR);
+ int uid = data.readInt();
+ remountUid(uid);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
}
@@ -2154,4 +2178,6 @@
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
throws RemoteException;
+
+ public void remountUid(int uid) throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 9b26f24..aab68e9 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -871,6 +871,15 @@
}
/** {@hide} */
+ public void remountUid(int uid) {
+ try {
+ mMountService.remountUid(uid);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;
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/CallLog.java b/core/java/android/provider/CallLog.java
index 7d57233..23555d6 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -518,11 +518,6 @@
if (callType == MISSED_TYPE) {
values.put(IS_READ, Integer.valueOf(0));
}
- if (ci != null) {
- values.put(CACHED_NAME, ci.name);
- values.put(CACHED_NUMBER_TYPE, ci.numberType);
- values.put(CACHED_NUMBER_LABEL, ci.numberLabel);
- }
if ((ci != null) && (ci.contactIdOrZero > 0)) {
// Update usage information for the number associated with the contact ID.
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/MediaStore.java b/core/java/android/provider/MediaStore.java
index 51dbdee3..e63fb04 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -283,7 +283,13 @@
* supply the uri through the EXTRA_OUTPUT field for compatibility with old applications.
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
- * @see #EXTRA_OUTPUT
+ *
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
+ * is not granted, then atempting to use this action will result in a {@link
+ * java.lang.SecurityException}.
+ *
+ * @see #EXTRA_OUTPUT
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -331,6 +337,12 @@
* supply the uri through the EXTRA_OUTPUT field for compatibility with old applications.
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
+ *
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
+ * is not granted, then atempting to use this action will result in a {@link
+ * java.lang.SecurityException}.
+ *
* @see #EXTRA_OUTPUT
* @see #EXTRA_VIDEO_QUALITY
* @see #EXTRA_SIZE_LIMIT
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 56cd1a7..e5afdde 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -562,6 +562,21 @@
"android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
/**
+ * Activity Action: Show settings to toggle permission to draw on top of
+ * other apps.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_OVERLAY_PERMISSION =
+ "android.settings.MANAGE_OVERLAY_PERMISSION";
+
+ /**
* Activity Action: Show screen of details about a particular application.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -5444,6 +5459,14 @@
public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled";
/**
+ * Specifies whether a screenshot of the screen contents will be sent to the assist
+ * application (active voice interaction service).
+ *
+ * @hide
+ */
+ public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
+
+ /**
* Names of the service components that the current user has explicitly allowed to
* see all of the user's notifications, separated by ':'.
*
@@ -6685,6 +6708,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/ExportResult.aidl b/core/java/android/security/keymaster/ExportResult.aidl
index f522355..4d9b2de 100644
--- a/core/java/android/security/keymaster/ExportResult.aidl
+++ b/core/java/android/security/keymaster/ExportResult.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,
diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java
index bb44c03..2b3ccbc 100644
--- a/core/java/android/security/keymaster/ExportResult.java
+++ b/core/java/android/security/keymaster/ExportResult.java
@@ -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,
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.aidl b/core/java/android/security/keymaster/KeyCharacteristics.aidl
index 15014b1..be739d3 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.aidl
+++ b/core/java/android/security/keymaster/KeyCharacteristics.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,
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index 03248e5..89300d1 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -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,
@@ -19,6 +19,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -30,8 +31,8 @@
public KeymasterArguments swEnforced;
public KeymasterArguments hwEnforced;
- public static final Parcelable.Creator<KeyCharacteristics> CREATOR = new
- Parcelable.Creator<KeyCharacteristics>() {
+ public static final Parcelable.Creator<KeyCharacteristics> CREATOR =
+ new Parcelable.Creator<KeyCharacteristics>() {
@Override
public KeyCharacteristics createFromParcel(Parcel in) {
return new KeyCharacteristics(in);
@@ -65,73 +66,85 @@
hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
}
- public Integer getInteger(int tag) {
+ /**
+ * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public Integer getEnum(int tag) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getInt(tag, -1);
+ return hwEnforced.getEnum(tag, -1);
} else if (swEnforced.containsTag(tag)) {
- return swEnforced.getInt(tag, -1);
+ return swEnforced.getEnum(tag, -1);
} else {
return null;
}
}
- public int getInt(int tag, int defaultValue) {
- Integer result = getInteger(tag);
- return (result != null) ? result : defaultValue;
- }
-
- public List<Integer> getInts(int tag) {
+ /**
+ * Returns all values of the specified repeating enum tag.
+ *
+ * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public List<Integer> getEnums(int tag) {
List<Integer> result = new ArrayList<Integer>();
- result.addAll(hwEnforced.getInts(tag));
- result.addAll(swEnforced.getInts(tag));
+ result.addAll(hwEnforced.getEnums(tag));
+ result.addAll(swEnforced.getEnums(tag));
return result;
}
- public Long getLong(int tag) {
+ /**
+ * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
+ * is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
+ */
+ public long getUnsignedInt(int tag, long defaultValue) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getLong(tag, -1);
- } else if (swEnforced.containsTag(tag)) {
- return swEnforced.getLong(tag, -1);
+ return hwEnforced.getUnsignedInt(tag, defaultValue);
} else {
- return null;
+ return swEnforced.getUnsignedInt(tag, defaultValue);
}
}
- public long getLong(int tag, long defaultValue) {
- Long result = getLong(tag);
- return (result != null) ? result : defaultValue;
- }
-
- public List<Long> getLongs(int tag) {
- List<Long> result = new ArrayList<Long>();
- result.addAll(hwEnforced.getLongs(tag));
- result.addAll(swEnforced.getLongs(tag));
+ /**
+ * Returns all values of the specified repeating unsigned 64-bit long tag.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
+ */
+ public List<BigInteger> getUnsignedLongs(int tag) {
+ List<BigInteger> result = new ArrayList<BigInteger>();
+ result.addAll(hwEnforced.getUnsignedLongs(tag));
+ result.addAll(swEnforced.getUnsignedLongs(tag));
return result;
}
+ /**
+ * Returns the value of the specified date tag or {@code null} if the tag is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
+ * represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
+ * epoch.
+ */
public Date getDate(int tag) {
- Date result = hwEnforced.getDate(tag, null);
- if (result == null) {
- result = swEnforced.getDate(tag, null);
+ Date result = swEnforced.getDate(tag, null);
+ if (result != null) {
+ return result;
}
- return result;
+ return hwEnforced.getDate(tag, null);
}
- public Date getDate(int tag, Date defaultValue) {
- if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getDate(tag, null);
- } else if (hwEnforced.containsTag(tag)) {
- return swEnforced.getDate(tag, null);
- } else {
- return defaultValue;
- }
- }
-
+ /**
+ * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
public boolean getBoolean(int tag) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getBoolean(tag, false);
+ return hwEnforced.getBoolean(tag);
} else {
- return swEnforced.getBoolean(tag, false);
+ return swEnforced.getBoolean(tag);
}
}
}
diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java
index 9adde35..6ad53a4 100644
--- a/core/java/android/security/keymaster/KeymasterArgument.java
+++ b/core/java/android/security/keymaster/KeymasterArgument.java
@@ -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,
@@ -32,17 +32,18 @@
public static final Parcelable.Creator<KeymasterArgument> CREATOR = new
Parcelable.Creator<KeymasterArgument>() {
+ @Override
public KeymasterArgument createFromParcel(Parcel in) {
final int pos = in.dataPosition();
final int tag = in.readInt();
switch (KeymasterDefs.getTagType(tag)) {
case KeymasterDefs.KM_ENUM:
case KeymasterDefs.KM_ENUM_REP:
- case KeymasterDefs.KM_INT:
- case KeymasterDefs.KM_INT_REP:
+ case KeymasterDefs.KM_UINT:
+ case KeymasterDefs.KM_UINT_REP:
return new KeymasterIntArgument(tag, in);
- case KeymasterDefs.KM_LONG:
- case KeymasterDefs.KM_LONG_REP:
+ case KeymasterDefs.KM_ULONG:
+ case KeymasterDefs.KM_ULONG_REP:
return new KeymasterLongArgument(tag, in);
case KeymasterDefs.KM_DATE:
return new KeymasterDateArgument(tag, in);
@@ -55,6 +56,8 @@
throw new ParcelFormatException("Bad tag: " + tag + " at " + pos);
}
}
+
+ @Override
public KeymasterArgument[] newArray(int size) {
return new KeymasterArgument[size];
}
diff --git a/core/java/android/security/keymaster/KeymasterArguments.aidl b/core/java/android/security/keymaster/KeymasterArguments.aidl
index 7aef5a6..1a73206 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.aidl
+++ b/core/java/android/security/keymaster/KeymasterArguments.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,
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 82f65c7..e862252 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -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,
@@ -19,6 +19,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -30,7 +31,14 @@
* @hide
*/
public class KeymasterArguments implements Parcelable {
- List<KeymasterArgument> mArguments;
+
+ private static final long UINT32_RANGE = 1L << 32;
+ public static final long UINT32_MAX_VALUE = UINT32_RANGE - 1;
+
+ private static final BigInteger UINT64_RANGE = BigInteger.ONE.shiftLeft(64);
+ public static final BigInteger UINT64_MAX_VALUE = UINT64_RANGE.subtract(BigInteger.ONE);
+
+ private List<KeymasterArgument> mArguments;
public static final Parcelable.Creator<KeymasterArguments> CREATOR = new
Parcelable.Creator<KeymasterArguments>() {
@@ -53,38 +61,281 @@
mArguments = in.createTypedArrayList(KeymasterArgument.CREATOR);
}
- public void addInt(int tag, int value) {
+ /**
+ * Adds an enum tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public void addEnum(int tag, int value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_ENUM) && (tagType != KeymasterDefs.KM_ENUM_REP)) {
+ throw new IllegalArgumentException("Not an enum or repeating enum tag: " + tag);
+ }
+ addEnumTag(tag, value);
+ }
+
+ /**
+ * Adds a repeated enum tag with the provided values.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public void addEnums(int tag, int... values) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM_REP) {
+ throw new IllegalArgumentException("Not a repeating enum tag: " + tag);
+ }
+ for (int value : values) {
+ addEnumTag(tag, value);
+ }
+ }
+
+ /**
+ * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public int getEnum(int tag, int defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM) {
+ throw new IllegalArgumentException("Not an enum tag: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
+ }
+ return getEnumTagValue(arg);
+ }
+
+ /**
+ * Returns all values of the specified repeating enum tag.
+ *
+ * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public List<Integer> getEnums(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM_REP) {
+ throw new IllegalArgumentException("Not a repeating enum tag: " + tag);
+ }
+ List<Integer> values = new ArrayList<Integer>();
+ for (KeymasterArgument arg : mArguments) {
+ if (arg.tag == tag) {
+ values.add(getEnumTagValue(arg));
+ }
+ }
+ return values;
+ }
+
+ private void addEnumTag(int tag, int value) {
mArguments.add(new KeymasterIntArgument(tag, value));
}
- public void addInts(int tag, int... values) {
- for (int value : values) {
- addInt(tag, value);
- }
+ private int getEnumTagValue(KeymasterArgument arg) {
+ return ((KeymasterIntArgument) arg).value;
}
- public void addLongs(int tag, long... values) {
- for (long value : values) {
- addLong(tag, value);
+ /**
+ * Adds an unsigned 32-bit int tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag or if
+ * {@code value} is outside of the permitted range [0; 2^32).
+ */
+ public void addUnsignedInt(int tag, long value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_UINT) && (tagType != KeymasterDefs.KM_UINT_REP)) {
+ throw new IllegalArgumentException("Not an int or repeating int tag: " + tag);
}
+ // Keymaster's KM_UINT is unsigned 32 bit.
+ if ((value < 0) || (value > UINT32_MAX_VALUE)) {
+ throw new IllegalArgumentException("Int tag value out of range: " + value);
+ }
+ mArguments.add(new KeymasterIntArgument(tag, (int) value));
}
+ /**
+ * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
+ * is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
+ */
+ public long getUnsignedInt(int tag, long defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_UINT) {
+ throw new IllegalArgumentException("Not an int tag: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
+ }
+ // Keymaster's KM_UINT is unsigned 32 bit.
+ return ((KeymasterIntArgument) arg).value & 0xffffffffL;
+ }
+
+ /**
+ * Adds an unsigned 64-bit long tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 64-bit long tag or if
+ * {@code value} is outside of the permitted range [0; 2^64).
+ */
+ public void addUnsignedLong(int tag, BigInteger value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_ULONG) && (tagType != KeymasterDefs.KM_ULONG_REP)) {
+ throw new IllegalArgumentException("Not a long or repeating long tag: " + tag);
+ }
+ addLongTag(tag, value);
+ }
+
+ /**
+ * Returns all values of the specified repeating unsigned 64-bit long tag.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
+ */
+ public List<BigInteger> getUnsignedLongs(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ULONG_REP) {
+ throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
+ }
+ List<BigInteger> values = new ArrayList<BigInteger>();
+ for (KeymasterArgument arg : mArguments) {
+ if (arg.tag == tag) {
+ values.add(getLongTagValue(arg));
+ }
+ }
+ return values;
+ }
+
+ private void addLongTag(int tag, BigInteger value) {
+ // Keymaster's KM_ULONG is unsigned 64 bit.
+ if ((value.signum() == -1) || (value.compareTo(UINT64_MAX_VALUE) > 0)) {
+ throw new IllegalArgumentException("Long tag value out of range: " + value);
+ }
+ mArguments.add(new KeymasterLongArgument(tag, value.longValue()));
+ }
+
+ private BigInteger getLongTagValue(KeymasterArgument arg) {
+ // Keymaster's KM_ULONG is unsigned 64 bit. We're forced to use BigInteger for type safety
+ // because there's no unsigned long type.
+ return toUint64(((KeymasterLongArgument) arg).value);
+ }
+
+ /**
+ * Adds the provided boolean tag. Boolean tags are considered to be set to {@code true} if
+ * present and {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
public void addBoolean(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
+ throw new IllegalArgumentException("Not a boolean tag: " + tag);
+ }
mArguments.add(new KeymasterBooleanArgument(tag));
}
- public void addLong(int tag, long value) {
- mArguments.add(new KeymasterLongArgument(tag, value));
+ /**
+ * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
+ public boolean getBoolean(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
+ throw new IllegalArgumentException("Not a boolean tag: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return false;
+ }
+ return true;
}
- public void addBlob(int tag, byte[] value) {
+ /**
+ * Adds a bytes tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a bytes tag.
+ */
+ public void addBytes(int tag, byte[] value) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BYTES) {
+ throw new IllegalArgumentException("Not a bytes tag: " + tag);
+ }
+ if (value == null) {
+ throw new NullPointerException("value == nulll");
+ }
mArguments.add(new KeymasterBlobArgument(tag, value));
}
+ /**
+ * Returns the value of the specified bytes tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a bytes tag.
+ */
+ public byte[] getBytes(int tag, byte[] defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BYTES) {
+ throw new IllegalArgumentException("Not a bytes tag: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
+ }
+ return ((KeymasterBlobArgument) arg).blob;
+ }
+
+ /**
+ * Adds a date tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if {@code value} is
+ * before the start of Unix epoch.
+ */
public void addDate(int tag, Date value) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+ throw new IllegalArgumentException("Not a date tag: " + tag);
+ }
+ if (value == null) {
+ throw new NullPointerException("value == nulll");
+ }
+ // Keymaster's KM_DATE is unsigned, but java.util.Date is signed, thus preventing us from
+ // using values larger than 2^63 - 1.
+ if (value.getTime() < 0) {
+ throw new IllegalArgumentException("Date tag value out of range: " + value);
+ }
mArguments.add(new KeymasterDateArgument(tag, value));
}
+ /**
+ * Adds a date tag with the provided value, if the value is not {@code null}. Does nothing if
+ * the {@code value} is null.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if {@code value} is
+ * before the start of Unix epoch.
+ */
+ public void addDateIfNotNull(int tag, Date value) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+ throw new IllegalArgumentException("Not a date tag: " + tag);
+ }
+ if (value != null) {
+ addDate(tag, value);
+ }
+ }
+
+ /**
+ * Returns the value of the specified date tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
+ * represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
+ * epoch.
+ */
+ public Date getDate(int tag, Date defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+ throw new IllegalArgumentException("Tag is not a date type: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
+ }
+ Date result = ((KeymasterDateArgument) arg).date;
+ // Keymaster's KM_DATE is unsigned, but java.util.Date is signed, thus preventing us from
+ // using values larger than 2^63 - 1.
+ if (result.getTime() < 0) {
+ throw new IllegalArgumentException("Tag value too large. Tag: " + tag);
+ }
+ return result;
+ }
+
private KeymasterArgument getArgumentByTag(int tag) {
for (KeymasterArgument arg : mArguments) {
if (arg.tag == tag) {
@@ -98,107 +349,6 @@
return getArgumentByTag(tag) != null;
}
- public int getInt(int tag, int defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_ENUM:
- case KeymasterDefs.KM_INT:
- break; // Accepted types
- case KeymasterDefs.KM_INT_REP:
- case KeymasterDefs.KM_ENUM_REP:
- throw new IllegalArgumentException("Repeatable tags must use getInts: " + tag);
- default:
- throw new IllegalArgumentException("Tag is not an int type: " + tag);
- }
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
- }
- return ((KeymasterIntArgument) arg).value;
- }
-
- public long getLong(int tag, long defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_LONG:
- break; // Accepted type
- case KeymasterDefs.KM_LONG_REP:
- throw new IllegalArgumentException("Repeatable tags must use getLongs: " + tag);
- default:
- throw new IllegalArgumentException("Tag is not a long type: " + tag);
- }
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
- }
- return ((KeymasterLongArgument) arg).value;
- }
-
- public Date getDate(int tag, Date defaultValue) {
- if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
- throw new IllegalArgumentException("Tag is not a date type: " + tag);
- }
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
- }
- return ((KeymasterDateArgument) arg).date;
- }
-
- public boolean getBoolean(int tag, boolean defaultValue) {
- if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
- throw new IllegalArgumentException("Tag is not a boolean type: " + tag);
- }
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
- }
- return true;
- }
-
- public byte[] getBlob(int tag, byte[] defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_BYTES:
- case KeymasterDefs.KM_BIGNUM:
- break; // Allowed types.
- default:
- throw new IllegalArgumentException("Tag is not a blob type: " + tag);
- }
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
- }
- return ((KeymasterBlobArgument) arg).blob;
- }
-
- public List<Integer> getInts(int tag) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_INT_REP:
- case KeymasterDefs.KM_ENUM_REP:
- break; // Allowed types.
- default:
- throw new IllegalArgumentException("Tag is not a repeating type: " + tag);
- }
- List<Integer> values = new ArrayList<Integer>();
- for (KeymasterArgument arg : mArguments) {
- if (arg.tag == tag) {
- values.add(((KeymasterIntArgument) arg).value);
- }
- }
- return values;
- }
-
- public List<Long> getLongs(int tag) {
- if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) {
- throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
- }
- List<Long> values = new ArrayList<Long>();
- for (KeymasterArgument arg : mArguments) {
- if (arg.tag == tag) {
- values.add(((KeymasterLongArgument) arg).value);
- }
- }
- return values;
- }
-
public int size() {
return mArguments.size();
}
@@ -216,4 +366,16 @@
public int describeContents() {
return 0;
}
+
+ /**
+ * Converts the provided value to non-negative {@link BigInteger}, treating the sign bit of the
+ * provided value as the most significant bit of the result.
+ */
+ public static BigInteger toUint64(long value) {
+ if (value >= 0) {
+ return BigInteger.valueOf(value);
+ } else {
+ return BigInteger.valueOf(value).add(UINT64_RANGE);
+ }
+ }
}
diff --git a/core/java/android/security/keymaster/KeymasterBlob.aidl b/core/java/android/security/keymaster/KeymasterBlob.aidl
index 8f70f7c..b7cd1c9 100644
--- a/core/java/android/security/keymaster/KeymasterBlob.aidl
+++ b/core/java/android/security/keymaster/KeymasterBlob.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,
diff --git a/core/java/android/security/keymaster/KeymasterBlob.java b/core/java/android/security/keymaster/KeymasterBlob.java
index cb95604..cd36870 100644
--- a/core/java/android/security/keymaster/KeymasterBlob.java
+++ b/core/java/android/security/keymaster/KeymasterBlob.java
@@ -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,
diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java
index 7d587bf5..541d33e 100644
--- a/core/java/android/security/keymaster/KeymasterBlobArgument.java
+++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java
@@ -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,
diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
index 9c03674..67b3281 100644
--- a/core/java/android/security/keymaster/KeymasterBooleanArgument.java
+++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
@@ -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,
diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java
index bffd24d..aa15e34 100644
--- a/core/java/android/security/keymaster/KeymasterDateArgument.java
+++ b/core/java/android/security/keymaster/KeymasterDateArgument.java
@@ -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,
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 3fb93c4..bae54559 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -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,
@@ -33,20 +33,20 @@
public static final int KM_INVALID = 0 << 28;
public static final int KM_ENUM = 1 << 28;
public static final int KM_ENUM_REP = 2 << 28;
- public static final int KM_INT = 3 << 28;
- public static final int KM_INT_REP = 4 << 28;
- public static final int KM_LONG = 5 << 28;
+ public static final int KM_UINT = 3 << 28;
+ public static final int KM_UINT_REP = 4 << 28;
+ public static final int KM_ULONG = 5 << 28;
public static final int KM_DATE = 6 << 28;
public static final int KM_BOOL = 7 << 28;
public static final int KM_BIGNUM = 8 << 28;
public static final int KM_BYTES = 9 << 28;
- public static final int KM_LONG_REP = 10 << 28;
+ public static final int KM_ULONG_REP = 10 << 28;
// Tag values.
public static final int KM_TAG_INVALID = KM_INVALID | 0;
public static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1;
public static final int KM_TAG_ALGORITHM = KM_ENUM | 2;
- public static final int KM_TAG_KEY_SIZE = KM_INT | 3;
+ public static final int KM_TAG_KEY_SIZE = KM_UINT | 3;
public static final int KM_TAG_BLOCK_MODE = KM_ENUM_REP | 4;
public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5;
public static final int KM_TAG_PADDING = KM_ENUM_REP | 6;
@@ -56,19 +56,19 @@
public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102;
public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 705;
- public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_LONG | 200;
+ public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200;
public static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400;
public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401;
public static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402;
- public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_INT | 403;
- public static final int KM_TAG_MAX_USES_PER_BOOT = KM_INT | 404;
+ public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_UINT | 403;
+ public static final int KM_TAG_MAX_USES_PER_BOOT = KM_UINT | 404;
public static final int KM_TAG_ALL_USERS = KM_BOOL | 500;
- public static final int KM_TAG_USER_ID = KM_INT | 501;
- public static final int KM_TAG_USER_SECURE_ID = KM_LONG_REP | 502;
+ public static final int KM_TAG_USER_ID = KM_UINT | 501;
+ public static final int KM_TAG_USER_SECURE_ID = KM_ULONG_REP | 502;
public static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503;
public static final int KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504;
- public static final int KM_TAG_AUTH_TIMEOUT = KM_INT | 505;
+ public static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505;
public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -81,8 +81,8 @@
public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000;
public static final int KM_TAG_NONCE = KM_BYTES | 1001;
- public static final int KM_TAG_AUTH_TOKEN = KM_BYTES | 1003;
- public static final int KM_TAG_MAC_LENGTH = KM_INT | 1004;
+ public static final int KM_TAG_AUTH_TOKEN = KM_BYTES | 1002;
+ public static final int KM_TAG_MAC_LENGTH = KM_UINT | 1003;
// Algorithm values.
public static final int KM_ALGORITHM_RSA = 1;
@@ -191,8 +191,9 @@
public static final int KM_ERROR_MISSING_NONCE = -51;
public static final int KM_ERROR_INVALID_NONCE = -52;
public static final int KM_ERROR_MISSING_MAC_LENGTH = -53;
- public static final int KM_ERROR_RESCOPABLE_KEY_NOT_USABLE = -54;
+ public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54;
public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55;
+ public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56;
public static final int KM_ERROR_UNIMPLEMENTED = -100;
public static final int KM_ERROR_VERSION_MISMATCH = -101;
public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java
index da81715..578d249 100644
--- a/core/java/android/security/keymaster/KeymasterIntArgument.java
+++ b/core/java/android/security/keymaster/KeymasterIntArgument.java
@@ -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,
@@ -27,8 +27,8 @@
public KeymasterIntArgument(int tag, int value) {
super(tag);
switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_INT:
- case KeymasterDefs.KM_INT_REP:
+ case KeymasterDefs.KM_UINT:
+ case KeymasterDefs.KM_UINT_REP:
case KeymasterDefs.KM_ENUM:
case KeymasterDefs.KM_ENUM_REP:
break; // OK.
diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java
index eb17b7e..d3d40ba 100644
--- a/core/java/android/security/keymaster/KeymasterLongArgument.java
+++ b/core/java/android/security/keymaster/KeymasterLongArgument.java
@@ -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,
@@ -27,8 +27,8 @@
public KeymasterLongArgument(int tag, long value) {
super(tag);
switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_LONG:
- case KeymasterDefs.KM_LONG_REP:
+ case KeymasterDefs.KM_ULONG:
+ case KeymasterDefs.KM_ULONG_REP:
break; // OK.
default:
throw new IllegalArgumentException("Bad long tag " + tag);
diff --git a/core/java/android/security/keymaster/OperationResult.aidl b/core/java/android/security/keymaster/OperationResult.aidl
index 699e8d0..ed26c8d 100644
--- a/core/java/android/security/keymaster/OperationResult.aidl
+++ b/core/java/android/security/keymaster/OperationResult.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,
diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java
index 30659662..4c962ec 100644
--- a/core/java/android/security/keymaster/OperationResult.java
+++ b/core/java/android/security/keymaster/OperationResult.java
@@ -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,
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/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 8c6cd09..d424546 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -41,6 +41,7 @@
import android.util.ArraySet;
import android.util.Log;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -368,7 +369,9 @@
/**
* Inform the notification manager that these notifications have been viewed by the
- * user.
+ * user. This should only be called when there is sufficient confidence that the user is
+ * looking at the notifications, such as when the notifications appear on the screen due to
+ * an explicit user interaction.
* @param keys Notifications to mark as seen.
*/
public final void setNotificationsShown(String[] keys) {
@@ -463,15 +466,28 @@
ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
.getActiveNotificationsFromListener(mWrapper, keys, trim);
List<StatusBarNotification> list = parceledList.getList();
-
+ ArrayList<StatusBarNotification> corruptNotifications = null;
int N = list.size();
for (int i = 0; i < N; i++) {
- Notification notification = list.get(i).getNotification();
- Builder.rebuild(getContext(), notification);
- // convert icon metadata to legacy format for older clients
- createLegacyIconExtras(notification);
+ StatusBarNotification sbn = list.get(i);
+ Notification notification = sbn.getNotification();
+ try {
+ Builder.rebuild(getContext(), notification);
+ // convert icon metadata to legacy format for older clients
+ createLegacyIconExtras(notification);
+ } catch (IllegalArgumentException e) {
+ if (corruptNotifications == null) {
+ corruptNotifications = new ArrayList<>(N);
+ }
+ corruptNotifications.add(sbn);
+ Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
+ sbn.getPackageName());
+ }
}
- return list.toArray(new StatusBarNotification[N]);
+ if (corruptNotifications != null) {
+ list.removeAll(corruptNotifications);
+ }
+ return list.toArray(new StatusBarNotification[list.size()]);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
}
@@ -671,16 +687,28 @@
Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
return;
}
- Notification.Builder.rebuild(getContext(), sbn.getNotification());
- // convert icon metadata to legacy format for older clients
- createLegacyIconExtras(sbn.getNotification());
+ try {
+ Notification.Builder.rebuild(getContext(), sbn.getNotification());
+ // convert icon metadata to legacy format for older clients
+ createLegacyIconExtras(sbn.getNotification());
+ } catch (IllegalArgumentException e) {
+ // drop corrupt notification
+ sbn = null;
+ Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
+ sbn.getPackageName());
+ }
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mWrapper) {
applyUpdate(update);
try {
- NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
+ if (sbn != null) {
+ NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
+ } else {
+ // still pass along the ranking map, it may contain other information
+ NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
+ }
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationPosted", t);
}
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/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 3eeb04a..eae4329 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1486,19 +1486,28 @@
// Get the default voice for the locale.
String voiceName = service.getDefaultVoiceNameFor(language, country, variant);
if (TextUtils.isEmpty(voiceName)) {
- Log.w(TAG, "Couldn't find the default voice for " + language + "/" +
- country + "/" + variant);
+ Log.w(TAG, "Couldn't find the default voice for " + language + "-" +
+ country + "-" + variant);
return LANG_NOT_SUPPORTED;
}
// Load it.
if (service.loadVoice(getCallerIdentity(), voiceName) == TextToSpeech.ERROR) {
+ Log.w(TAG, "The service claimed " + language + "-" + country + "-"
+ + variant + " was available with voice name " + voiceName
+ + " but loadVoice returned ERROR");
return LANG_NOT_SUPPORTED;
}
// Set the language/country/variant of the voice, so #getLanguage will return
// the currently set voice locale when called.
Voice voice = getVoice(service, voiceName);
+ if (voice == null) {
+ Log.w(TAG, "getDefaultVoiceNameFor returned " + voiceName + " for locale "
+ + language + "-" + country + "-" + variant
+ + " but getVoice returns null");
+ return LANG_NOT_SUPPORTED;
+ }
String voiceLanguage = "";
try {
voiceLanguage = voice.getLocale().getISO3Language();
@@ -1682,6 +1691,7 @@
private Voice getVoice(ITextToSpeechService service, String voiceName) throws RemoteException {
List<Voice> voices = service.getVoices();
if (voices == null) {
+ Log.w(TAG, "getVoices returned null");
return null;
}
for (Voice voice : voices) {
@@ -1689,6 +1699,7 @@
return voice;
}
}
+ Log.w(TAG, "Could not find voice " + voiceName + " in voice list");
return null;
}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index ba98f27..fa015b2 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -293,7 +293,9 @@
}
Set<String> features = onGetFeaturesForLanguage(locale.getISO3Language(),
locale.getISO3Country(), locale.getVariant());
- voices.add(new Voice(locale.toLanguageTag(), locale, Voice.QUALITY_NORMAL,
+ String voiceName = onGetDefaultVoiceNameFor(locale.getISO3Language(),
+ locale.getISO3Country(), locale.getVariant());
+ voices.add(new Voice(voiceName, locale, Voice.QUALITY_NORMAL,
Voice.LATENCY_NORMAL, false, features));
}
return voices;
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 464710b..b6fa4e4c 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -714,6 +714,27 @@
float[] lineWidths = lineBreaks.widths;
int[] flags = lineBreaks.flags;
+ final int remainingLineCount = mMaximumVisibleLineCount - mLineCount;
+ final boolean ellipsisMayBeApplied = ellipsize != null
+ && (ellipsize == TextUtils.TruncateAt.END
+ || (mMaximumVisibleLineCount == 1
+ && ellipsize != TextUtils.TruncateAt.MARQUEE));
+ if (remainingLineCount < breakCount && ellipsisMayBeApplied) {
+ // Treat the last line and overflowed lines as a single line.
+ breaks[remainingLineCount - 1] = breaks[breakCount - 1];
+ // Calculate width and flag.
+ float width = 0;
+ int flag = 0;
+ for (int i = remainingLineCount - 1; i < breakCount; i++) {
+ width += lineWidths[i];
+ flag |= flags[i] & TAB_MASK;
+ }
+ lineWidths[remainingLineCount - 1] = width;
+ flags[remainingLineCount - 1] = flag;
+
+ breakCount = remainingLineCount;
+ }
+
// here is the offset of the starting character of the line we are currently measuring
int here = paraStart;
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..82689b9 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);
@@ -98,32 +105,45 @@
mult = TrafficStats.PB_IN_BYTES;
result = result / 1024;
}
- String value;
+ // Note we calculate the rounded long by ourselves, but still let String.format()
+ // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
+ // floating point errors.
+ final int roundFactor;
+ final String roundFormat;
if (result < 1) {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
} else if (result < 10) {
if ((flags & FLAG_SHORTER) != 0) {
- value = String.format("%.1f", result);
+ roundFactor = 10;
+ roundFormat = "%.1f";
} else {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
}
} else if (result < 100) {
if ((flags & FLAG_SHORTER) != 0) {
- value = String.format("%.0f", result);
+ roundFactor = 1;
+ roundFormat = "%.0f";
} else {
- value = String.format("%.2f", result);
+ roundFactor = 100;
+ roundFormat = "%.2f";
}
} else {
- value = String.format("%.0f", result);
+ roundFactor = 1;
+ roundFormat = "%.0f";
}
+ final String roundedString = String.format(roundFormat, result);
+
+ // Note this might overflow if result >= Long.MAX_VALUE / 100, but that's like 80PB so
+ // it's okay (for now)...
+ final long roundedBytes =
+ (flags & FLAG_CALCULATE_ROUNDED) == 0 ? 0
+ : (((long) Math.round(result * roundFactor)) * mult / roundFactor);
+
final String units = res.getString(suffix);
- final long roundedBytes;
- if ((flags & FLAG_CALCULATE_ROUNDED) != 0) {
- roundedBytes = (long) (Double.parseDouble(value) * mult);
- } else {
- roundedBytes = 0;
- }
- return new BytesResult(value, units, roundedBytes);
+
+ return new BytesResult(roundedString, units, roundedBytes);
}
/**
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 5dda8a7..3688cfa 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -147,24 +147,13 @@
* @throws IllegalArgumentException is offset is not valid.
*/
public int getBeginning(int offset) {
- final int shiftedOffset = offset - mOffsetShift;
- checkOffsetIsValid(shiftedOffset);
-
- if (isOnLetterOrDigit(shiftedOffset)) {
- if (mIterator.isBoundary(shiftedOffset)) {
- return shiftedOffset + mOffsetShift;
- } else {
- return mIterator.preceding(shiftedOffset) + mOffsetShift;
- }
- } else {
- if (isAfterLetterOrDigit(shiftedOffset)) {
- return mIterator.preceding(shiftedOffset) + mOffsetShift;
- }
- }
- return BreakIterator.DONE;
+ // TODO: Check if usage of this can be updated to getBeginning(offset, true) if
+ // so this method can be removed.
+ return getBeginning(offset, false);
}
- /** If <code>offset</code> is within a word, returns the index of the last character of that
+ /**
+ * If <code>offset</code> is within a word, returns the index of the last character of that
* word plus one, otherwise returns BreakIterator.DONE.
*
* The offsets that are considered to be part of a word are the indexes of its characters,
@@ -177,11 +166,106 @@
* @throws IllegalArgumentException is offset is not valid.
*/
public int getEnd(int offset) {
+ // TODO: Check if usage of this can be updated to getEnd(offset, true), if
+ // so this method can be removed.
+ return getEnd(offset, false);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the start of a word (e.g. _word where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the first character of
+ * that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, this would return the start of the previous word, AA.
+ *
+ * Returns BreakIterator.DONE if there is no previous boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ public int getPrevWordBeginningOnTwoWordsBoundary(int offset) {
+ return getBeginning(offset, true);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the end of a word (e.g. word_ where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the last character
+ * plus one of that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, this would return the end of the next word, BB.
+ *
+ * Returns BreakIterator.DONE if there is no next boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ public int getNextWordEndOnTwoWordBoundary(int offset) {
+ return getEnd(offset, true);
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the start of a word (e.g. _word where "_" is any character that would not
+ * be considered part of the word) then this returns the index of the first character of
+ * that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, and getPrevWordBeginningOnTwoWordsBoundary is true then this would
+ * return the start of the previous word, AA. Otherwise it would return the current offset,
+ * the start of BB.
+ *
+ * Returns BreakIterator.DONE if there is no previous boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ private int getBeginning(int offset, boolean getPrevWordBeginningOnTwoWordsBoundary) {
+ final int shiftedOffset = offset - mOffsetShift;
+ checkOffsetIsValid(shiftedOffset);
+
+ if (isOnLetterOrDigit(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)
+ && (!isAfterLetterOrDigit(shiftedOffset)
+ || !getPrevWordBeginningOnTwoWordsBoundary)) {
+ return shiftedOffset + mOffsetShift;
+ } else {
+ return mIterator.preceding(shiftedOffset) + mOffsetShift;
+ }
+ } else {
+ if (isAfterLetterOrDigit(shiftedOffset)) {
+ return mIterator.preceding(shiftedOffset) + mOffsetShift;
+ }
+ }
+ return BreakIterator.DONE;
+ }
+
+ /**
+ * If the <code>offset</code> is within a word or on a word boundary that can only be
+ * considered the end of a word (e.g. word_ where "_" is any character that would not be
+ * considered part of the word) then this returns the index of the last character plus one
+ * of that word.
+ *
+ * If the offset is on a word boundary that can be considered the start and end of a
+ * word, e.g. AABB (where AA and BB are both words) and the offset is the boundary
+ * between AA and BB, and getNextWordEndOnTwoWordBoundary is true then this would return
+ * the end of the next word, BB. Otherwise it would return the current offset, the end
+ * of AA.
+ *
+ * Returns BreakIterator.DONE if there is no next boundary.
+ *
+ * @throws IllegalArgumentException is offset is not valid.
+ */
+ private int getEnd(int offset, boolean getNextWordEndOnTwoWordBoundary) {
final int shiftedOffset = offset - mOffsetShift;
checkOffsetIsValid(shiftedOffset);
if (isAfterLetterOrDigit(shiftedOffset)) {
- if (mIterator.isBoundary(shiftedOffset)) {
+ if (mIterator.isBoundary(shiftedOffset)
+ && (!isOnLetterOrDigit(shiftedOffset) || !getNextWordEndOnTwoWordBoundary)) {
return shiftedOffset + mOffsetShift;
} else {
return mIterator.following(shiftedOffset) + mOffsetShift;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c61ca4e..e958058 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -528,11 +528,13 @@
ArrayMap<View, TransitionValues> unmatchedEnd) {
for (int i = unmatchedStart.size() - 1; i >= 0; i--) {
View view = unmatchedStart.keyAt(i);
- TransitionValues end = unmatchedEnd.remove(view);
- if (end != null) {
- TransitionValues start = unmatchedStart.removeAt(i);
- mStartValuesList.add(start);
- mEndValuesList.add(end);
+ if (view != null && isValidTarget(view)) {
+ TransitionValues end = unmatchedEnd.remove(view);
+ if (end != null && end.view != null && isValidTarget(end.view)) {
+ TransitionValues start = unmatchedStart.removeAt(i);
+ mStartValuesList.add(start);
+ mEndValuesList.add(end);
+ }
}
}
}
@@ -548,9 +550,9 @@
int numStartIds = startItemIds.size();
for (int i = 0; i < numStartIds; i++) {
View startView = startItemIds.valueAt(i);
- if (startView != null) {
+ if (startView != null && isValidTarget(startView)) {
View endView = endItemIds.get(startItemIds.keyAt(i));
- if (endView != null) {
+ if (endView != null && isValidTarget(endView)) {
TransitionValues startValues = unmatchedStart.get(startView);
TransitionValues endValues = unmatchedEnd.get(endView);
if (startValues != null && endValues != null) {
@@ -626,14 +628,20 @@
ArrayMap<View, TransitionValues> unmatchedEnd) {
// Views that only exist in the start Scene
for (int i = 0; i < unmatchedStart.size(); i++) {
- mStartValuesList.add(unmatchedStart.valueAt(i));
- mEndValuesList.add(null);
+ final TransitionValues start = unmatchedStart.valueAt(i);
+ if (isValidTarget(start.view)) {
+ mStartValuesList.add(start);
+ mEndValuesList.add(null);
+ }
}
// Views that only exist in the end Scene
for (int i = 0; i < unmatchedEnd.size(); i++) {
- mEndValuesList.add(unmatchedEnd.valueAt(i));
- mStartValuesList.add(null);
+ final TransitionValues end = unmatchedEnd.valueAt(i);
+ if (isValidTarget(end.view)) {
+ mEndValuesList.add(end);
+ mStartValuesList.add(null);
+ }
}
}
@@ -1046,7 +1054,7 @@
*/
public Transition removeTarget(int targetId) {
if (targetId > 0) {
- mTargetIds.remove(targetId);
+ mTargetIds.remove((Integer)targetId);
}
return this;
}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 5209f90..71c8099 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -435,10 +435,11 @@
sPendingTransitions.remove(sceneRoot);
final ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
- if (runningTransitions != null) {
- final int count = runningTransitions.size();
- for (int i = 0; i < count; i++) {
- final Transition transition = runningTransitions.get(i);
+ if (runningTransitions != null && !runningTransitions.isEmpty()) {
+ // Make a copy in case this is called by an onTransitionEnd listener
+ ArrayList<Transition> copy = new ArrayList(runningTransitions);
+ for (int i = copy.size() - 1; i >= 0; i--) {
+ final Transition transition = copy.get(i);
transition.end();
}
}
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/LocalLog.java b/core/java/android/util/LocalLog.java
index cab5d19..4862f01 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -54,4 +54,18 @@
pw.println(itr.next());
}
}
+
+ public static class ReadOnlyLocalLog {
+ private final LocalLog mLog;
+ ReadOnlyLocalLog(LocalLog log) {
+ mLog = log;
+ }
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mLog.dump(fd, pw, args);
+ }
+ }
+
+ public ReadOnlyLocalLog readOnlyLocalLog() {
+ return new ReadOnlyLocalLog(this);
+ }
}
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/ActionMode.java b/core/java/android/view/ActionMode.java
index 80dcecc..ea979c8 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -261,6 +261,16 @@
public abstract MenuInflater getMenuInflater();
/**
+ * Called when the window containing the view that started this action mode gains or loses
+ * focus.
+ *
+ * @param hasWindowFocus True if the window containing the view that started this action mode
+ * now has focus, false otherwise.
+ *
+ */
+ public void onWindowFocusChanged(boolean hasWindowFocus) {}
+
+ /**
* Returns whether the UI presenting this action mode can take focus or not.
* This is used by internal components within the framework that would otherwise
* present an action mode UI that requires focus, such as an EditText as a custom view.
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/InputDevice.java b/core/java/android/view/InputDevice.java
index f39d1f5..cc4598d1 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -201,6 +201,35 @@
public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER;
/**
+ * The input device is a Bluetooth stylus.
+ * <p>
+ * Note that this bit merely indicates that an input device is capable of
+ * obtaining input from a Bluetooth stylus. To determine whether a given
+ * touch event was produced by a stylus, examine the tool type returned by
+ * {@link MotionEvent#getToolType(int)} for each individual pointer.
+ * </p><p>
+ * A single touch event may multiple pointers with different tool types,
+ * such as an event that has one pointer with tool type
+ * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
+ * {@link MotionEvent#TOOL_TYPE_STYLUS}. So it is important to examine
+ * the tool type of each pointer, regardless of the source reported
+ * by {@link MotionEvent#getSource()}.
+ * </p><p>
+ * A bluetooth stylus generally receives its pressure and button state
+ * information from the stylus itself, and derives the rest from another
+ * source. For example, a Bluetooth stylus used in conjunction with a
+ * touchscreen would derive its contact position and pointer size from the
+ * touchscreen and may not be any more accurate than other tools such as
+ * fingers.
+ * </p>
+ *
+ * @see #SOURCE_STYLUS
+ * @see #SOURCE_CLASS_POINTER
+ */
+ public static final int SOURCE_BLUETOOTH_STYLUS =
+ 0x00008000 | SOURCE_STYLUS;
+
+ /**
* The input source is a trackball.
*
* @see #SOURCE_CLASS_TRACKBALL
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..23da6d2 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);
@@ -6179,6 +6179,10 @@
structure.setId(id, null, null, null);
}
structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
+ if (!hasIdentityMatrix()) {
+ structure.setTransformation(getMatrix());
+ }
+ structure.setElevation(getZ());
structure.setVisibility(getVisibility());
structure.setEnabled(isEnabled());
if (isClickable()) {
@@ -6215,11 +6219,6 @@
structure.setContentDescription(getContentDescription());
}
- /** @hide */
- public void onProvideAssistStructure(ViewStructure structure) {
- onProvideStructure(structure);
- }
-
/**
* Called when assist structure is being retrieved from a view as part of
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
@@ -6232,7 +6231,6 @@
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) {
AccessibilityNodeInfo info = createAccessibilityNodeInfo();
- Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
structure.setChildCount(1);
ViewStructure root = structure.newChild(0);
populateVirtualStructure(root, provider, info);
@@ -6240,11 +6238,6 @@
}
}
- /** @hide */
- public void onProvideVirtualAssistStructure(ViewStructure structure) {
- onProvideVirtualStructure(structure);
- }
-
private void populateVirtualStructure(ViewStructure structure,
AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
@@ -6284,8 +6277,6 @@
CharSequence cname = info.getClassName();
structure.setClassName(cname != null ? cname.toString() : null);
structure.setContentDescription(info.getContentDescription());
- Log.i("View", "vassist " + cname + " @ " + rect.toShortString()
- + " text=" + info.getText() + " cd=" + info.getContentDescription());
if (info.getText() != null || info.getError() != null) {
structure.setText(info.getText(), info.getTextSelectionStart(),
info.getTextSelectionEnd());
@@ -6310,8 +6301,8 @@
*/
public void dispatchProvideStructure(ViewStructure structure) {
if (!isAssistBlocked()) {
- onProvideAssistStructure(structure);
- onProvideVirtualAssistStructure(structure);
+ onProvideStructure(structure);
+ onProvideVirtualStructure(structure);
} else {
structure.setClassName(getAccessibilityClassName().toString());
structure.setAssistBlocked(true);
@@ -6326,6 +6317,10 @@
* @hide
*/
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ if (mAttachInfo == null) {
+ return;
+ }
+
Rect bounds = mAttachInfo.mTmpInvalRect;
getDrawingRect(bounds);
@@ -8706,14 +8701,14 @@
}
/**
- * Adds the children of a given View for accessibility. Since some Views are
- * not important for accessibility the children for accessibility are not
- * necessarily direct children of the view, rather they are the first level of
- * descendants important for accessibility.
+ * Adds the children of this View relevant for accessibility to the given list
+ * as output. Since some Views are not important for accessibility the added
+ * child views are not necessarily direct children of this view, rather they are
+ * the first level of descendants important for accessibility.
*
- * @param children The list of children for accessibility.
+ * @param outChildren The output list that will receive children for accessibility.
*/
- public void addChildrenForAccessibility(ArrayList<View> children) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
}
@@ -8774,7 +8769,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 +8791,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) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2e2ba88..6dca26b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1919,7 +1919,7 @@
}
@Override
- public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
if (getAccessibilityNodeProvider() != null) {
return;
}
@@ -1930,9 +1930,9 @@
View child = children.getChildAt(i);
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
if (child.includeForAccessibility()) {
- childrenForAccessibility.add(child);
+ outChildren.add(child);
} else {
- child.addChildrenForAccessibility(childrenForAccessibility);
+ child.addChildrenForAccessibility(outChildren);
}
}
}
@@ -3236,13 +3236,15 @@
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- Insets insets = c.getOpticalInsets();
+ if (c.getVisibility() != View.GONE) {
+ Insets insets = c.getOpticalInsets();
- drawRect(canvas, paint,
- c.getLeft() + insets.left,
- c.getTop() + insets.top,
- c.getRight() - insets.right - 1,
- c.getBottom() - insets.bottom - 1);
+ drawRect(canvas, paint,
+ c.getLeft() + insets.left,
+ c.getTop() + insets.top,
+ c.getRight() - insets.right - 1,
+ c.getBottom() - insets.bottom - 1);
+ }
}
}
@@ -3263,8 +3265,10 @@
int lineWidth = dipsToPixels(1);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
- paint, lineLength, lineWidth);
+ if (c.getVisibility() != View.GONE) {
+ drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
+ paint, lineLength, lineWidth);
+ }
}
}
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index d06cd83..794622a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -16,6 +16,7 @@
package android.view;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
@@ -50,6 +51,28 @@
int height);
/**
+ * Set the transformation matrix associated with this view, as per
+ * {@link View#getMatrix View.getMatrix()}, or null if there is none.
+ */
+ public abstract void setTransformation(Matrix matrix);
+
+ /**
+ * Set the visual elevation (shadow) of the view, as per
+ * {@link View#getZ View.getZ()}. Note this is <em>not</em> related
+ * to the physical Z-ordering of this view relative to its other siblings (that is how
+ * they overlap when drawing), it is only the visual representation for shadowing.
+ */
+ public abstract void setElevation(float elevation);
+
+ /**
+ * Set an alpha transformation that is applied to this view, as per
+ * {@link View#getAlpha View.getAlpha()}. Value ranges from 0
+ * (completely transparent) to 1 (completely opaque); the default is 1, which means
+ * no transformation.
+ */
+ public abstract void setAlpha(float alpha);
+
+ /**
* Set the visibility state of this view, as per
* {@link View#getVisibility View.getVisibility()}.
*/
@@ -150,7 +173,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 +244,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 +254,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..1464bb5 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -689,6 +689,11 @@
public static final int TYPE_VIEW_CONTEXT_CLICKED = 0x00800000;
/**
+ * Represents the event of the assistant currently reading the users screen context.
+ */
+ public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000;
+
+ /**
* Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
* The type of change is not defined.
*/
@@ -1115,7 +1120,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 +1172,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 +1199,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 ");
@@ -1409,6 +1419,13 @@
builder.append("TYPE_VIEW_CONTEXT_CLICKED");
eventTypeCount++;
}
+ case TYPE_ASSIST_READING_CONTEXT: {
+ if (eventTypeCount > 0) {
+ builder.append(", ");
+ }
+ builder.append("TYPE_ASSIST_READING_CONTEXT");
+ eventTypeCount++;
+ }
break;
}
}
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/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index b4ef58a..3b9aca8 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -96,49 +96,27 @@
public MissingWebViewPackageException(Exception e) { super(e); }
}
- /** @hide */
- public static String[] getWebViewPackageNames() {
- return AppGlobals.getInitialApplication().getResources().getStringArray(
- com.android.internal.R.array.config_webViewPackageNames);
- }
-
- // TODO (gsennton) remove when committing webview xts test change
public static String getWebViewPackageName() {
- String[] webViewPackageNames = getWebViewPackageNames();
- return webViewPackageNames[webViewPackageNames.length-1];
+ return AppGlobals.getInitialApplication().getString(
+ com.android.internal.R.string.config_webViewPackageName);
}
- /**
- * Return the package info of the first package in the webview priority list that contains
- * webview.
- *
- * @hide
- */
- public static PackageInfo findPreferredWebViewPackage() {
+ private static PackageInfo fetchPackageInfo() {
PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
-
- for (String packageName : getWebViewPackageNames()) {
- try {
- PackageInfo packageInfo = pm.getPackageInfo(packageName,
- PackageManager.GET_META_DATA);
- ApplicationInfo applicationInfo = packageInfo.applicationInfo;
-
- // If the correct flag is set the package contains webview.
- if (getWebViewLibrary(applicationInfo) != null) {
- return packageInfo;
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
+ try {
+ return pm.getPackageInfo(getWebViewPackageName(), PackageManager.GET_META_DATA);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new MissingWebViewPackageException(e);
}
- throw new MissingWebViewPackageException("Could not find a loadable WebView package");
}
// throws MissingWebViewPackageException
private static ApplicationInfo getWebViewApplicationInfo() {
- if (sPackageInfo == null)
- return findPreferredWebViewPackage().applicationInfo;
- else
+ if (sPackageInfo == null) {
+ return fetchPackageInfo().applicationInfo;
+ } else {
return sPackageInfo.applicationInfo;
+ }
}
private static String getWebViewLibrary(ApplicationInfo ai) {
@@ -153,10 +131,10 @@
/**
* Load the native library for the given package name iff that package
- * name is the same as the one providing the current webview.
+ * name is the same as the one providing the webview.
*/
public static int loadWebViewNativeLibraryFromPackage(String packageName) {
- sPackageInfo = findPreferredWebViewPackage();
+ sPackageInfo = fetchPackageInfo();
if (packageName != null && packageName.equals(sPackageInfo.packageName)) {
return loadNativeLibrary();
}
@@ -202,7 +180,7 @@
private static Class<WebViewFactoryProvider> getProviderClass() {
try {
// First fetch the package info so we can log the webview package version.
- sPackageInfo = findPreferredWebViewPackage();
+ sPackageInfo = fetchPackageInfo();
Log.i(LOGTAG, "Loading " + sPackageInfo.packageName + " version " +
sPackageInfo.versionName + " (code " + sPackageInfo.versionCode + ")");
@@ -241,8 +219,8 @@
try {
// Construct a package context to load the Java code into the current app.
Context webViewContext = initialApplication.createPackageContext(
- sPackageInfo.packageName,
- Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ sPackageInfo.packageName,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
initialApplication.getAssets().addAssetPath(
webViewContext.getApplicationInfo().sourceDir);
ClassLoader clazzLoader = webViewContext.getClassLoader();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a96bf71..8bf6992 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6605,6 +6605,8 @@
void addScrapView(View scrap, int position) {
final AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
if (lp == null) {
+ // Can't recycle, skip the scrap heap.
+ getSkippedScrap().add(scrap);
return;
}
@@ -6614,6 +6616,8 @@
// should otherwise not be recycled.
final int viewType = lp.viewType;
if (!shouldRecycleViewType(viewType)) {
+ // Can't recycle, skip the scrap heap.
+ getSkippedScrap().add(scrap);
return;
}
@@ -6633,22 +6637,19 @@
// If the adapter has stable IDs, we can reuse the view for
// the same data.
if (mTransientStateViewsById == null) {
- mTransientStateViewsById = new LongSparseArray<View>();
+ mTransientStateViewsById = new LongSparseArray<>();
}
mTransientStateViewsById.put(lp.itemId, scrap);
} else if (!mDataChanged) {
// If the data hasn't changed, we can reuse the views at
// their old positions.
if (mTransientStateViews == null) {
- mTransientStateViews = new SparseArray<View>();
+ mTransientStateViews = new SparseArray<>();
}
mTransientStateViews.put(position, scrap);
} else {
// Otherwise, we'll have to remove the view and start over.
- if (mSkippedScrap == null) {
- mSkippedScrap = new ArrayList<View>();
- }
- mSkippedScrap.add(scrap);
+ getSkippedScrap().add(scrap);
}
} else {
if (mViewTypeCount == 1) {
@@ -6663,6 +6664,13 @@
}
}
+ private ArrayList<View> getSkippedScrap() {
+ if (mSkippedScrap == null) {
+ mSkippedScrap = new ArrayList<>();
+ }
+ return mSkippedScrap;
+ }
+
/**
* Finish the removal of any views that skipped the scrap heap.
*/
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index a15080e..ebb54ff 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -17,6 +17,7 @@
package android.widget;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
@@ -24,6 +25,7 @@
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.RemoteViews.RemoteView;
import java.util.Formatter;
@@ -58,6 +60,7 @@
}
private long mBase;
+ private long mNow; // the currently displayed time
private boolean mVisible;
private boolean mStarted;
private boolean mRunning;
@@ -224,6 +227,7 @@
}
private synchronized void updateText(long now) {
+ mNow = now;
long seconds = now - mBase;
seconds /= 1000;
String text = DateUtils.formatElapsedTime(mRecycle, seconds);
@@ -279,6 +283,60 @@
}
}
+ private static final int MIN_IN_SEC = 60;
+ private static final int HOUR_IN_SEC = MIN_IN_SEC*60;
+ private static String formatDuration(long ms) {
+ final Resources res = Resources.getSystem();
+ final StringBuilder text = new StringBuilder();
+
+ int duration = (int) (ms / DateUtils.SECOND_IN_MILLIS);
+ if (duration < 0) {
+ duration = -duration;
+ }
+
+ int h = 0;
+ int m = 0;
+
+ if (duration >= HOUR_IN_SEC) {
+ h = duration / HOUR_IN_SEC;
+ duration -= h * HOUR_IN_SEC;
+ }
+ if (duration >= MIN_IN_SEC) {
+ m = duration / MIN_IN_SEC;
+ duration -= m * MIN_IN_SEC;
+ }
+ int s = duration;
+
+ try {
+ if (h > 0) {
+ text.append(res.getQuantityString(
+ com.android.internal.R.plurals.duration_hours, h, h));
+ }
+ if (m > 0) {
+ if (text.length() > 0) {
+ text.append(' ');
+ }
+ text.append(res.getQuantityString(
+ com.android.internal.R.plurals.duration_minutes, m, m));
+ }
+
+ if (text.length() > 0) {
+ text.append(' ');
+ }
+ text.append(res.getQuantityString(
+ com.android.internal.R.plurals.duration_seconds, s, s));
+ } catch (Resources.NotFoundException e) {
+ // Ignore; plurals throws an exception for an untranslated quantity for a given locale.
+ return null;
+ }
+ return text.toString();
+ }
+
+ @Override
+ public CharSequence getContentDescription() {
+ return formatDuration(mNow - mBase);
+ }
+
@Override
public CharSequence getAccessibilityClassName() {
return Chronometer.class.getName();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 9ca59f1..84e7db4 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -123,6 +123,7 @@
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
private static final float LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS = 0.5f;
+ private static final int UNSET_X_VALUE = -1;
// Tag used when the Editor maintains its own separate UndoManager.
private static final String UNDO_OWNER_TAG = "Editor";
@@ -393,7 +394,7 @@
}
mPreserveDetachedSelection = true;
- hideControllers();
+ hideCursorAndSpanControllers();
stopTextActionMode();
mPreserveDetachedSelection = false;
mTemporaryDetach = false;
@@ -605,9 +606,9 @@
}
/**
- * Hides the insertion controller and stops text selection mode, hiding the selection controller
+ * Hides the insertion and span controllers.
*/
- void hideControllers() {
+ void hideCursorAndSpanControllers() {
hideCursorControllers();
hideSpanControllers();
}
@@ -623,7 +624,7 @@
// One is the true focus lost where suggestions pop-up (if any) should be dismissed, and the
// other is an side effect of showing the suggestions pop-up itself. We use isShowingUp()
// to distinguish one from the other.
- if (mSuggestionsPopupWindow != null && ((mTextView instanceof ExtractEditText) ||
+ if (mSuggestionsPopupWindow != null && ((mTextView.isInExtractedMode()) ||
!mSuggestionsPopupWindow.isShowingUp())) {
// Should be done before hide insertion point controller since it triggers a show of it
mSuggestionsPopupWindow.hide();
@@ -640,7 +641,7 @@
mTextView.removeAdjacentSuggestionSpans(end);
if (mTextView.isTextEditable() && mTextView.isSuggestionsEnabled() &&
- !(mTextView instanceof ExtractEditText)) {
+ !(mTextView.isInExtractedMode())) {
if (mSpellChecker == null && createSpellChecker) {
mSpellChecker = new SpellChecker(mTextView);
}
@@ -735,7 +736,7 @@
retOffset = getWordIteratorWithText().getPunctuationBeginning(offset);
} else {
// Not on a punctuation boundary, find the word start.
- retOffset = getWordIteratorWithText().getBeginning(offset);
+ retOffset = getWordIteratorWithText().getPrevWordBeginningOnTwoWordsBoundary(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -750,7 +751,7 @@
retOffset = getWordIteratorWithText().getPunctuationEnd(offset);
} else {
// Not on a punctuation boundary, find the word end.
- retOffset = getWordIteratorWithText().getEnd(offset);
+ retOffset = getWordIteratorWithText().getNextWordEndOnTwoWordBoundary(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -1063,7 +1064,7 @@
// ExtractEditText clears focus, which gives focus to the ExtractEditText.
// This special case ensure that we keep current selection in that case.
// It would be better to know why the DecorView does not have focus at that time.
- if (((mTextView instanceof ExtractEditText) || mSelectionMoved) &&
+ if (((mTextView.isInExtractedMode()) || mSelectionMoved) &&
selStart >= 0 && selEnd >= 0) {
/*
* Someone intentionally set the selection, so let them
@@ -1099,17 +1100,17 @@
// Don't leave us in the middle of a batch edit.
mTextView.onEndBatchEdit();
- if (mTextView instanceof ExtractEditText) {
+ if (mTextView.isInExtractedMode()) {
// terminateTextSelectionMode removes selection, which we want to keep when
// ExtractEditText goes out of focus.
final int selStart = mTextView.getSelectionStart();
final int selEnd = mTextView.getSelectionEnd();
- hideControllers();
+ hideCursorAndSpanControllers();
stopTextActionMode();
Selection.setSelection((Spannable) mTextView.getText(), selStart, selEnd);
} else {
if (mTemporaryDetach) mPreserveDetachedSelection = true;
- hideControllers();
+ hideCursorAndSpanControllers();
stopTextActionMode();
if (mTemporaryDetach) mPreserveDetachedSelection = false;
downgradeEasyCorrectionSpans();
@@ -1182,6 +1183,12 @@
mBlink.uncancel();
makeBlink();
}
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ final boolean immFullScreen = (imm != null && imm.isFullscreenMode());
+ if (mSelectionModifierCursorController != null && mTextView.hasSelection()
+ && !immFullScreen) {
+ mSelectionModifierCursorController.show();
+ }
} else {
if (mBlink != null) {
mBlink.cancel();
@@ -1190,7 +1197,10 @@
mInputContentType.enterDown = false;
}
// Order matters! Must be done before onParentLostFocus to rely on isShowingUp
- hideControllers();
+ hideCursorAndSpanControllers();
+ if (mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.hide();
+ }
if (mSuggestionsPopupWindow != null) {
mSuggestionsPopupWindow.onParentLostFocus();
}
@@ -1825,7 +1835,7 @@
}
private boolean extractedTextModeWillBeStarted() {
- if (!(mTextView instanceof ExtractEditText)) {
+ if (!(mTextView.isInExtractedMode())) {
final InputMethodManager imm = InputMethodManager.peekInstance();
return imm != null && imm.isFullscreenMode();
}
@@ -1913,7 +1923,7 @@
void onTouchUpEvent(MotionEvent event) {
boolean selectAllGotFocus = mSelectAllOnFocus && mTextView.didTouchFocusSelect();
- hideControllers();
+ hideCursorAndSpanControllers();
stopTextActionMode();
CharSequence text = mTextView.getText();
if (!selectAllGotFocus && text.length() > 0) {
@@ -2034,7 +2044,7 @@
if (mSuggestionsPopupWindow == null) {
mSuggestionsPopupWindow = new SuggestionsPopupWindow();
}
- hideControllers();
+ hideCursorAndSpanControllers();
stopTextActionMode();
mSuggestionsPopupWindow.show();
}
@@ -4058,6 +4068,10 @@
private boolean mInWord = false;
// Difference between touch position and word boundary position.
private float mTouchWordDelta;
+ // X value of the previous updatePosition call.
+ private float mPrevX;
+ // Indicates if the handle has moved a boundary between LTR and RTL text.
+ private boolean mLanguageDirectionChanged = false;
public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -4118,13 +4132,56 @@
int end = getWordEnd(offset);
int start = getWordStart(offset);
- if (offset < mPreviousOffset) {
+ if (mPrevX == UNSET_X_VALUE) {
+ mPrevX = x;
+ }
+
+ final int selectionStart = mTextView.getSelectionStart();
+ final boolean selectionStartRtl = layout.isRtlCharAt(selectionStart);
+ final boolean atRtl = layout.isRtlCharAt(offset);
+ final boolean isLvlBoundary = layout.isLevelBoundary(offset);
+ boolean isExpanding;
+
+ // We can't determine if the user is expanding or shrinking the selection if they're
+ // on a bi-di boundary, so until they've moved past the boundary we'll just place
+ // the cursor at the current position.
+ if (isLvlBoundary || (selectionStartRtl && !atRtl) || (!selectionStartRtl && atRtl)) {
+ // We're on a boundary or this is the first direction change -- just update
+ // to the current position.
+ mLanguageDirectionChanged = true;
+ mTouchWordDelta = 0.0f;
+ positionAtCursorOffset(offset, false);
+ return;
+ } else if (mLanguageDirectionChanged && !isLvlBoundary) {
+ // We've just moved past the boundary so update the position. After this we can
+ // figure out if the user is expanding or shrinking to go by word or character.
+ positionAtCursorOffset(offset, false);
+ mTouchWordDelta = 0.0f;
+ mLanguageDirectionChanged = false;
+ return;
+ } else {
+ final float xDiff = x - mPrevX;
+ if (atRtl) {
+ isExpanding = xDiff > 0 || currLine > mPrevLine;
+ } else {
+ isExpanding = xDiff < 0 || currLine < mPrevLine;
+ }
+ }
+
+ if (isExpanding) {
// User is increasing the selection.
if (!mInWord || currLine < mPrevLine) {
- // We're not in a word, or we're on a different line so we'll expand by
- // word. First ensure the user has at least entered the next word.
- int offsetToWord = Math.min((end - start) / 2, 2);
- if (offset <= end - offsetToWord || currLine < mPrevLine) {
+ // Sometimes words can be broken across lines (Chinese, hyphenation).
+ // We still snap to the start of the word but we only use the letters on the
+ // current line to determine if the user is far enough into the word to snap.
+ int wordStartOnCurrLine = start;
+ if (layout != null && layout.getLineForOffset(start) != currLine) {
+ wordStartOnCurrLine = layout.getLineStart(currLine);
+ }
+ int offsetThresholdToSnap = end - ((end - wordStartOnCurrLine) / 2);
+ if (offset <= offsetThresholdToSnap || currLine < mPrevLine) {
+ // User is far enough into the word or on a different
+ // line so we expand by word.
offset = start;
} else {
offset = mPreviousOffset;
@@ -4173,6 +4230,7 @@
}
positionAtCursorOffset(offset, false);
}
+ mPrevX = x;
}
@Override
@@ -4187,6 +4245,7 @@
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
mTouchWordDelta = 0.0f;
+ mPrevX = UNSET_X_VALUE;
}
return superResult;
}
@@ -4197,6 +4256,10 @@
private boolean mInWord = false;
// Difference between touch position and word boundary position.
private float mTouchWordDelta;
+ // X value of the previous updatePosition call.
+ private float mPrevX;
+ // Indicates if the handle has moved a boundary between LTR and RTL text.
+ private boolean mLanguageDirectionChanged = false;
public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -4257,13 +4320,56 @@
int end = getWordEnd(offset);
int start = getWordStart(offset);
- if (offset > mPreviousOffset) {
+ if (mPrevX == UNSET_X_VALUE) {
+ mPrevX = x;
+ }
+
+ final int selectionEnd = mTextView.getSelectionEnd();
+ final boolean selectionEndRtl = layout.isRtlCharAt(selectionEnd);
+ final boolean atRtl = layout.isRtlCharAt(offset);
+ final boolean isLvlBoundary = layout.isLevelBoundary(offset);
+ boolean isExpanding;
+
+ // We can't determine if the user is expanding or shrinking the selection if they're
+ // on a bi-di boundary, so until they've moved past the boundary we'll just place
+ // the cursor at the current position.
+ if (isLvlBoundary || (selectionEndRtl && !atRtl) || (!selectionEndRtl && atRtl)) {
+ // We're on a boundary or this is the first direction change -- just update
+ // to the current position.
+ mLanguageDirectionChanged = true;
+ mTouchWordDelta = 0.0f;
+ positionAtCursorOffset(offset, false);
+ return;
+ } else if (mLanguageDirectionChanged && !isLvlBoundary) {
+ // We've just moved past the boundary so update the position. After this we can
+ // figure out if the user is expanding or shrinking to go by word or character.
+ positionAtCursorOffset(offset, false);
+ mTouchWordDelta = 0.0f;
+ mLanguageDirectionChanged = false;
+ return;
+ } else {
+ final float xDiff = x - mPrevX;
+ if (atRtl) {
+ isExpanding = xDiff < 0 || currLine < mPrevLine;
+ } else {
+ isExpanding = xDiff > 0 || currLine > mPrevLine;
+ }
+ }
+
+ if (isExpanding) {
// User is increasing the selection.
if (!mInWord || currLine > mPrevLine) {
- // We're not in a word, or we're on a different line so we'll expand by
- // word. First ensure the user has at least entered the next word.
- int midPoint = Math.min((end - start) / 2, 2);
- if (offset >= start + midPoint || currLine > mPrevLine) {
+ // Sometimes words can be broken across lines (Chinese, hyphenation).
+ // We still snap to the end of the word but we only use the letters on the
+ // current line to determine if the user is far enough into the word to snap.
+ int wordEndOnCurrLine = end;
+ if (layout != null && layout.getLineForOffset(end) != currLine) {
+ wordEndOnCurrLine = layout.getLineEnd(currLine);
+ }
+ final int offsetThresholdToSnap = start + ((wordEndOnCurrLine - start) / 2);
+ if (offset >= offsetThresholdToSnap || currLine > mPrevLine) {
+ // User is far enough into the word or on a different
+ // line so we expand by word.
offset = end;
} else {
offset = mPreviousOffset;
@@ -4312,6 +4418,7 @@
}
positionAtCursorOffset(offset, false);
}
+ mPrevX = x;
}
@Override
@@ -4326,6 +4433,7 @@
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
mTouchWordDelta = 0.0f;
+ mPrevX = UNSET_X_VALUE;
}
return superResult;
}
@@ -4517,34 +4625,39 @@
final float eventY = event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
+ if (extractedTextModeWillBeStarted()) {
+ // Prevent duplicating the selection handles until the mode starts.
+ hide();
+ } else {
+ // Remember finger down position, to be able to start selection from there.
+ mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition(
+ eventX, eventY);
- // Remember finger down position, to be able to start selection from there.
- mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition(
- eventX, eventY);
+ // Double tap detection
+ if (mGestureStayedInTapRegion) {
+ if (mDoubleTap) {
+ final float deltaX = eventX - mDownPositionX;
+ final float deltaY = eventY - mDownPositionY;
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- // Double tap detection
- if (mGestureStayedInTapRegion) {
- if (mDoubleTap) {
- final float deltaX = eventX - mDownPositionX;
- final float deltaY = eventY - mDownPositionY;
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ ViewConfiguration viewConfiguration = ViewConfiguration.get(
+ mTextView.getContext());
+ int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
+ boolean stayedInArea =
+ distanceSquared < doubleTapSlop * doubleTapSlop;
- ViewConfiguration viewConfiguration = ViewConfiguration.get(
- mTextView.getContext());
- int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
- boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop;
-
- if (stayedInArea && isPositionOnText(eventX, eventY)) {
- selectCurrentWordAndStartDrag();
- mDiscardNextActionUp = true;
+ if (stayedInArea && isPositionOnText(eventX, eventY)) {
+ selectCurrentWordAndStartDrag();
+ mDiscardNextActionUp = true;
+ }
}
}
- }
- mDownPositionX = eventX;
- mDownPositionY = eventY;
- mGestureStayedInTapRegion = true;
- mHaventMovedEnoughToStartDrag = true;
+ mDownPositionX = eventX;
+ mDownPositionY = eventY;
+ mGestureStayedInTapRegion = true;
+ mHaventMovedEnoughToStartDrag = true;
+ }
break;
case MotionEvent.ACTION_POINTER_DOWN:
@@ -4657,7 +4770,9 @@
mEndHandle.showAtLocation(endOffset);
// No longer the first dragging motion, reset.
- startSelectionActionMode();
+ if (!(mTextView.isInExtractedMode())) {
+ startSelectionActionMode();
+ }
mDragAcceleratorActive = false;
mStartOffset = -1;
mSwitchedLines = false;
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 11d7026..c40289e 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -660,10 +660,11 @@
maxWidth = containerWidth - adjacent.getRight();
}
- final int adjMaxWidth = maxWidth - marginLeft - marginRight;
+ final int adjMaxHeight = Math.max(0, container.height());
+ final int adjMaxWidth = Math.max(0, maxWidth - marginLeft - marginRight);
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
- MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
+ adjMaxHeight, MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
// Align to the left or right.
@@ -700,10 +701,11 @@
final Rect container = mContainerRect;
final int containerWidth = container.width();
- final int adjMaxWidth = containerWidth - marginLeft - marginRight;
+ final int adjMaxHeight = Math.max(0, container.height());
+ final int adjMaxWidth = Math.max(0, containerWidth - marginLeft - marginRight);
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
- MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
+ adjMaxHeight, MeasureSpec.UNSPECIFIED);
preview.measure(widthMeasureSpec, heightMeasureSpec);
// Align at the vertical center, 10% from the top.
@@ -766,10 +768,11 @@
final View track = mTrackImage;
final View thumb = mThumbImage;
final Rect container = mContainerRect;
- final int maxWidth = container.width();
+ final int maxWidth = Math.max(0, container.width());
+ final int maxHeight = Math.max(0, container.height());
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
- MeasureSpec.UNSPECIFIED);
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
+ maxHeight, MeasureSpec.UNSPECIFIED);
track.measure(widthMeasureSpec, heightMeasureSpec);
final int top;
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 7ca450a..280ff15 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -230,28 +230,29 @@
if (count > 1) {
for (int i = 0; i < count; i++) {
final View child = mMatchParentChildren.get(i);
-
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
- int childWidthMeasureSpec;
- int childHeightMeasureSpec;
-
+
+ final int childWidthMeasureSpec;
if (lp.width == LayoutParams.MATCH_PARENT) {
- childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() -
- getPaddingLeftWithForeground() - getPaddingRightWithForeground() -
- lp.leftMargin - lp.rightMargin,
- MeasureSpec.EXACTLY);
+ final int width = Math.max(0, getMeasuredWidth()
+ - getPaddingLeftWithForeground() - getPaddingRightWithForeground()
+ - lp.leftMargin - lp.rightMargin);
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ width, MeasureSpec.EXACTLY);
} else {
childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
getPaddingLeftWithForeground() + getPaddingRightWithForeground() +
lp.leftMargin + lp.rightMargin,
lp.width);
}
-
+
+ final int childHeightMeasureSpec;
if (lp.height == LayoutParams.MATCH_PARENT) {
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() -
- getPaddingTopWithForeground() - getPaddingBottomWithForeground() -
- lp.topMargin - lp.bottomMargin,
- MeasureSpec.EXACTLY);
+ final int height = Math.max(0, getMeasuredHeight()
+ - getPaddingTopWithForeground() - getPaddingBottomWithForeground()
+ - lp.topMargin - lp.bottomMargin);
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ height, MeasureSpec.EXACTLY);
} else {
childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
getPaddingTopWithForeground() + getPaddingBottomWithForeground() +
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index e0b2395..a1582f2 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -423,14 +423,14 @@
*
* <p class="note">This does Bitmap reading and decoding on the UI
* thread, which can cause a latency hiccup. If that's a concern,
- * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
+ * consider using {@link #setImageDrawable(Drawable)} or
* {@link #setImageBitmap(android.graphics.Bitmap)} and
* {@link android.graphics.BitmapFactory} instead.</p>
*
- * @param uri The Uri of an image
+ * @param uri the Uri of an image, or {@code null} to clear the content
*/
@android.view.RemotableViewMethod
- public void setImageURI(Uri uri) {
+ public void setImageURI(@Nullable Uri uri) {
if (mResource != 0 ||
(mUri != uri &&
(uri == null || mUri == null || !uri.equals(mUri)))) {
@@ -453,9 +453,10 @@
/**
* Sets a drawable as the content of this ImageView.
*
- * @param drawable The drawable to set
+ * @param drawable the Drawable to set, or {@code null} to clear the
+ * content
*/
- public void setImageDrawable(Drawable drawable) {
+ public void setImageDrawable(@Nullable Drawable drawable) {
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
@@ -475,16 +476,19 @@
/**
* Sets the content of this ImageView to the specified Icon.
*
- * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding
- * on the UI thread, which can cause UI jank. If that's a concern, consider using
+ * <p class="note">Depending on the Icon type, this may do Bitmap reading
+ * and decoding on the UI thread, which can cause UI jank. If that's a
+ * concern, consider using
* {@link Icon#loadDrawableAsync(Context, Icon.OnDrawableLoadedListener, Handler)}
- * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p>
+ * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)}
+ * instead.</p>
*
- * @param icon an Icon holding the desired image
+ * @param icon an Icon holding the desired image, or {@code null} to clear
+ * the content
*/
@android.view.RemotableViewMethod
- public void setImageIcon(Icon icon) {
- setImageDrawable(icon.loadDrawable(mContext));
+ public void setImageIcon(@Nullable Icon icon) {
+ setImageDrawable(icon == null ? null : icon.loadDrawable(mContext));
}
/**
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 056323db..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -359,7 +359,7 @@
}
if (hasDividerBeforeChildAt(count)) {
- final View child = getVirtualChildAt(count - 1);
+ final View child = getLastNonGoneChild();
int bottom = 0;
if (child == null) {
bottom = getHeight() - getPaddingBottom() - mDividerHeight;
@@ -371,6 +371,20 @@
}
}
+ /**
+ * Finds the last child that is not gone. The last child will be used as the reference for
+ * where the end divider should be drawn.
+ */
+ private View getLastNonGoneChild() {
+ for (int i = getVirtualChildCount() - 1; i >= 0; i--) {
+ View child = getVirtualChildAt(i);
+ if (child != null && child.getVisibility() != GONE) {
+ return child;
+ }
+ }
+ return null;
+ }
+
void drawDividersHorizontal(Canvas canvas) {
final int count = getVirtualChildCount();
final boolean isLayoutRtl = isLayoutRtl();
@@ -392,7 +406,7 @@
}
if (hasDividerBeforeChildAt(count)) {
- final View child = getVirtualChildAt(count - 1);
+ final View child = getLastNonGoneChild();
int position;
if (child == null) {
if (isLayoutRtl) {
@@ -627,21 +641,30 @@
* @hide Pending API consideration. Currently only used internally by the system.
*/
protected boolean hasDividerBeforeChildAt(int childIndex) {
- if (childIndex == 0) {
- return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;
- } else if (childIndex == getChildCount()) {
+ if (childIndex == getVirtualChildCount()) {
+ // Check whether the end divider should draw.
return (mShowDividers & SHOW_DIVIDER_END) != 0;
- } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
- boolean hasVisibleViewBefore = false;
- for (int i = childIndex - 1; i >= 0; i--) {
- if (getChildAt(i).getVisibility() != GONE) {
- hasVisibleViewBefore = true;
- break;
- }
- }
- return hasVisibleViewBefore;
}
- return false;
+ boolean allViewsAreGoneBefore = allViewsAreGoneBefore(childIndex);
+ if (allViewsAreGoneBefore) {
+ // This is the first view that's not gone, check if beginning divider is enabled.
+ return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;
+ } else {
+ return (mShowDividers & SHOW_DIVIDER_MIDDLE) != 0;
+ }
+ }
+
+ /**
+ * Checks whether all (virtual) child views before the given index are gone.
+ */
+ private boolean allViewsAreGoneBefore(int childIndex) {
+ for (int i = childIndex - 1; i >= 0; i--) {
+ View child = getVirtualChildAt(i);
+ if (child != null && child.getVisibility() != GONE) {
+ return false;
+ }
+ }
+ return true;
}
/**
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index afc683a..c6de5dd 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -105,7 +105,7 @@
private final ListSelectorHider mHideSelector = new ListSelectorHider();
private Runnable mShowDropDownRunnable;
- private Handler mHandler = new Handler();
+ private final Handler mHandler;
private Rect mTempRect = new Rect();
@@ -212,6 +212,7 @@
*/
public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
mContext = context;
+ mHandler = new Handler(context.getMainLooper());
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPopupWindow,
defStyleAttr, defStyleRes);
@@ -1126,10 +1127,19 @@
break;
}
- // measure the hint's height to find how much more vertical space
- // we need to add to the drop down's height
- int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST);
- int heightSpec = MeasureSpec.UNSPECIFIED;
+ // Measure the hint's height to find how much more vertical
+ // space we need to add to the drop down's height.
+ final int widthSize;
+ final int widthMode;
+ if (mDropDownWidth >= 0) {
+ widthMode = MeasureSpec.AT_MOST;
+ widthSize = mDropDownWidth;
+ } else {
+ widthMode = MeasureSpec.UNSPECIFIED;
+ widthSize = 0;
+ }
+ final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
+ final int heightSpec = MeasureSpec.UNSPECIFIED;
hintView.measure(widthSpec, heightSpec);
hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams();
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index fd0395a..9568492 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1143,8 +1143,8 @@
// Sets up mListPadding
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
@@ -1153,10 +1153,12 @@
int childState = 0;
mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
- if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
- heightMode == MeasureSpec.UNSPECIFIED)) {
+ if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED
+ || heightMode == MeasureSpec.UNSPECIFIED)) {
final View child = obtainView(0, mIsScrap);
+ // Lay out child directly against the parent measure spec so that
+ // we can obtain exected minimum width and height.
measureScrapChild(child, 0, widthMeasureSpec, heightSize);
childWidth = child.getMeasuredWidth();
@@ -1173,7 +1175,7 @@
widthSize = mListPadding.left + mListPadding.right + childWidth +
getVerticalScrollbarWidth();
} else {
- widthSize |= (childState&MEASURED_STATE_MASK);
+ widthSize |= (childState & MEASURED_STATE_MASK);
}
if (heightMode == MeasureSpec.UNSPECIFIED) {
@@ -1186,8 +1188,9 @@
heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
}
- setMeasuredDimension(widthSize , heightSize);
- mWidthMeasureSpec = widthMeasureSpec;
+ setMeasuredDimension(widthSize, heightSize);
+
+ mWidthMeasureSpec = widthMeasureSpec;
}
private void measureScrapChild(View child, int position, int widthMeasureSpec, int heightHint) {
@@ -1199,16 +1202,20 @@
p.viewType = mAdapter.getItemViewType(position);
p.forceAdd = true;
- int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
- int lpHeight = p.height;
- int childHeightSpec;
+ final int lpHeight = p.height;
+ final int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeSafeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
+
+ // Since this view was measured directly aginst the parent measure
+ // spec, we must measure it again before reuse.
+ child.forceLayout();
}
/**
@@ -1248,8 +1255,7 @@
* @return The height of this ListView with the given children.
*/
final int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
- final int maxHeight, int disallowPartialChildPosition) {
-
+ int maxHeight, int disallowPartialChildPosition) {
final ListAdapter adapter = mAdapter;
if (adapter == null) {
return mListPadding.top + mListPadding.bottom;
@@ -1907,8 +1913,8 @@
}
p.viewType = mAdapter.getItemViewType(position);
- if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter &&
- p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
+ if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter
+ && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
attachViewToParent(child, flowDown ? -1 : 0, p);
} else {
p.forceAdd = false;
@@ -1936,10 +1942,10 @@
}
if (needToMeasure) {
- int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
- int lpHeight = p.height;
- int childHeightSpec;
+ final int lpHeight = p.height;
+ final int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index e7d9226..b5fae4e 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -149,6 +149,11 @@
private static final int SIZE_UNSPECIFIED = -1;
/**
+ * User choice on whether the selector wheel should be wrapped.
+ */
+ private boolean mWrapSelectorWheelPreferred = true;
+
+ /**
* Use a custom NumberPicker formatting callback to use two-digit minutes
* strings like "01". Keeping a static formatter etc. is the most efficient
* way to do this; it avoids creating temporary objects on every call to
@@ -1353,10 +1358,21 @@
* @param wrapSelectorWheel Whether to wrap.
*/
public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
+ mWrapSelectorWheelPreferred = wrapSelectorWheel;
+ updateWrapSelectorWheel();
+
+ }
+
+ /**
+ * Whether or not the selector wheel should be wrapped is determined by user choice and whether
+ * the choice is allowed. The former comes from {@link #setWrapSelectorWheel(boolean)}, the
+ * latter is calculated based on min & max value set vs selector's visual length. Therefore,
+ * this method should be called any time any of the 3 values (i.e. user choice, min and max
+ * value) gets updated.
+ */
+ private void updateWrapSelectorWheel() {
final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length;
- if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) {
- mWrapSelectorWheel = wrapSelectorWheel;
- }
+ mWrapSelectorWheel = wrappingAllowed && mWrapSelectorWheelPreferred;
}
/**
@@ -1412,8 +1428,7 @@
if (mMinValue > mValue) {
mValue = mMinValue;
}
- boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
- setWrapSelectorWheel(wrapSelectorWheel);
+ updateWrapSelectorWheel();
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
@@ -1450,8 +1465,7 @@
if (mMaxValue < mValue) {
mValue = mMaxValue;
}
- boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
- setWrapSelectorWheel(wrapSelectorWheel);
+ updateWrapSelectorWheel();
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 451e493..98bfd7d 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -731,7 +731,7 @@
// mStartTime has been set
mFinished = false;
mState = CUBIC;
- mStart = start;
+ mCurrentPosition = mStart = start;
mFinal = end;
final int delta = start - end;
mDeceleration = getDeceleration(delta);
@@ -797,7 +797,9 @@
private void fitOnBounceCurve(int start, int end, int velocity) {
// Simulate a bounce that started from edge
final float durationToApex = - velocity / mDeceleration;
- final float distanceToApex = velocity * velocity / 2.0f / Math.abs(mDeceleration);
+ // The float cast below is necessary to avoid integer overflow.
+ final float velocitySquared = (float) velocity * velocity;
+ final float distanceToApex = velocitySquared / 2.0f / Math.abs(mDeceleration);
final float distanceToEdge = Math.abs(end - start);
final float totalDuration = (float) Math.sqrt(
2.0 * (distanceToApex + distanceToEdge) / Math.abs(mDeceleration));
@@ -848,12 +850,14 @@
private void onEdgeReached() {
// mStart, mVelocity and mStartTime were adjusted to their values when edge was reached.
- float distance = mVelocity * mVelocity / (2.0f * Math.abs(mDeceleration));
+ // The float cast below is necessary to avoid integer overflow.
+ final float velocitySquared = (float) mVelocity * mVelocity;
+ float distance = velocitySquared / (2.0f * Math.abs(mDeceleration));
final float sign = Math.signum(mVelocity);
if (distance > mOver) {
// Default deceleration is not sufficient to slow us down before boundary
- mDeceleration = - sign * mVelocity * mVelocity / (2.0f * mOver);
+ mDeceleration = - sign * velocitySquared / (2.0f * mOver);
distance = mOver;
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 339038e..dac02fa 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -763,19 +763,19 @@
}
// Figure out maximum size available to this view
- int maxAvailable = tempEnd - tempStart;
+ final int maxAvailable = tempEnd - tempStart;
if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) {
- // Constraints fixed both edges, so child must be an exact size
+ // Constraints fixed both edges, so child must be an exact size.
childSpecMode = MeasureSpec.EXACTLY;
- childSpecSize = maxAvailable;
+ childSpecSize = Math.max(0, maxAvailable);
} else {
if (childSize >= 0) {
- // Child wanted an exact size. Give as much as possible
+ // Child wanted an exact size. Give as much as possible.
childSpecMode = MeasureSpec.EXACTLY;
if (maxAvailable >= 0) {
- // We have a maxmum size in this dimension.
+ // We have a maximum size in this dimension.
childSpecSize = Math.min(maxAvailable, childSize);
} else {
// We can grow in this dimension.
@@ -783,20 +783,19 @@
}
} else if (childSize == LayoutParams.MATCH_PARENT) {
// Child wanted to be as big as possible. Give all available
- // space
+ // space.
childSpecMode = MeasureSpec.EXACTLY;
- childSpecSize = maxAvailable;
+ childSpecSize = Math.max(0, maxAvailable);
} else if (childSize == LayoutParams.WRAP_CONTENT) {
- // Child wants to wrap content. Use AT_MOST
- // to communicate available space if we know
- // our max size
+ // Child wants to wrap content. Use AT_MOST to communicate
+ // available space if we know our max size.
if (maxAvailable >= 0) {
// We have a maximum size in this dimension.
childSpecMode = MeasureSpec.AT_MOST;
childSpecSize = maxAvailable;
} else {
// We can grow in this dimension. Child can be as big as it
- // wants
+ // wants.
childSpecMode = MeasureSpec.UNSPECIFIED;
childSpecSize = 0;
}
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/Switch.java b/core/java/android/widget/Switch.java
index 49226cd0..f45e750 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -242,6 +242,38 @@
com.android.internal.R.styleable.Switch_switchPadding, 0);
mSplitTrack = a.getBoolean(com.android.internal.R.styleable.Switch_splitTrack, false);
+ ColorStateList thumbTintList = a.getColorStateList(
+ com.android.internal.R.styleable.Switch_thumbTint);
+ if (thumbTintList != null) {
+ mThumbTintList = thumbTintList;
+ mHasThumbTint = true;
+ }
+ PorterDuff.Mode thumbTintMode = Drawable.parseTintMode(
+ a.getInt(com.android.internal.R.styleable.Switch_thumbTintMode, -1), null);
+ if (mThumbTintMode != thumbTintMode) {
+ mThumbTintMode = thumbTintMode;
+ mHasThumbTintMode = true;
+ }
+ if (mHasThumbTint || mHasThumbTintMode) {
+ applyThumbTint();
+ }
+
+ ColorStateList trackTintList = a.getColorStateList(
+ com.android.internal.R.styleable.Switch_trackTint);
+ if (trackTintList != null) {
+ mTrackTintList = trackTintList;
+ mHasTrackTint = true;
+ }
+ PorterDuff.Mode trackTintMode = Drawable.parseTintMode(
+ a.getInt(com.android.internal.R.styleable.Switch_trackTintMode, -1), null);
+ if (mTrackTintMode != trackTintMode) {
+ mTrackTintMode = trackTintMode;
+ mHasTrackTintMode = true;
+ }
+ if (mHasTrackTint || mHasTrackTintMode) {
+ applyTrackTint();
+ }
+
final int appearance = a.getResourceId(
com.android.internal.R.styleable.Switch_switchTextAppearance, 0);
if (appearance != 0) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c538dc2..422511f 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;
@@ -292,6 +292,9 @@
// New state used to change background based on whether this TextView is multiline.
private static final int[] MULTILINE_STATE_SET = { R.attr.state_multiline };
+ // Accessibility action to share selected text.
+ private static final int ACCESSIBILITY_ACTION_SHARE = 0x10000000;
+
// System wide time for last cut, copy or text changed action.
static long sLastCutCopyOrTextChangedTime;
@@ -5230,7 +5233,8 @@
// Phone specific code (there is no ExtractEditText on tablets).
// ExtractEditText does not call onFocus when it is displayed, and mHasSelectionOnFocus can
// not be set. Do the test here instead.
- if (this instanceof ExtractEditText && hasSelection() && mEditor != null) {
+ if (isInExtractedMode() && hasSelection() && mEditor != null
+ && mEditor.mTextActionMode == null && isShown() && hasWindowFocus()) {
mEditor.startSelectionActionMode();
}
@@ -5848,31 +5852,43 @@
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- boolean isInSelectionMode = mEditor != null && mEditor.mTextActionMode != null;
-
- if (isInSelectionMode) {
- if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
- if (state != null) {
- state.startTracking(event, this);
- }
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
- if (state != null) {
- state.handleUpEvent(event);
- }
- if (event.isTracking() && !event.isCanceled()) {
- stopTextActionMode();
- return true;
- }
- }
- }
+ // Note: If the IME is in fullscreen mode and IMS#mExtractEditText is in text action mode,
+ // InputMethodService#onKeyDown and InputMethodService#onKeyUp are responsible to call
+ // InputMethodService#mExtractEditText.maybeHandleBackInTextActionMode(event).
+ if (keyCode == KeyEvent.KEYCODE_BACK && handleBackInTextActionModeIfNeeded(event)) {
+ return true;
}
return super.onKeyPreIme(keyCode, event);
}
+ /**
+ * @hide
+ */
+ public boolean handleBackInTextActionModeIfNeeded(KeyEvent event) {
+ // Do nothing unless mEditor is in text action mode.
+ if (mEditor == null || mEditor.mTextActionMode == null) {
+ return false;
+ }
+
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ stopTextActionMode();
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
int which = doKeyDown(keyCode, event, null);
@@ -6363,7 +6379,7 @@
// This would stop a possible selection mode, but no such mode is started in case
// extracted mode will start. Some text is selected though, and will trigger an action mode
// in the extracted view.
- mEditor.hideControllers();
+ mEditor.hideCursorAndSpanControllers();
stopTextActionMode();
}
@@ -7561,10 +7577,14 @@
}
String getSelectedText() {
- if (hasSelection()) {
- return String.valueOf(mText.subSequence(getSelectionStart(), getSelectionEnd()));
+ if (!hasSelection()) {
+ return null;
}
- return null;
+
+ final int start = getSelectionStart();
+ final int end = getSelectionEnd();
+ return String.valueOf(
+ start > end ? mText.subSequence(end, start) : mText.subSequence(start, end));
}
/**
@@ -8192,7 +8212,7 @@
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (mEditor != null && visibility != VISIBLE) {
- mEditor.hideControllers();
+ mEditor.hideCursorAndSpanControllers();
stopTextActionMode();
}
}
@@ -8637,6 +8657,15 @@
}
/**
+ * @return true if this TextView is specialized for showing and interacting with the extracted
+ * text in a full-screen input method.
+ * @hide
+ */
+ public boolean isInExtractedMode() {
+ return false;
+ }
+
+ /**
* This is a temporary method. Future versions may support multi-locale text.
* Caveat: This method may not return the latest spell checker locale, but this should be
* acceptable and it's more important to make this method asynchronous.
@@ -8808,12 +8837,10 @@
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+ info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
}
if (isFocused()) {
- if (canSelectText()) {
- info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
- }
if (canCopy()) {
info.addAction(AccessibilityNodeInfo.ACTION_COPY);
}
@@ -8823,6 +8850,11 @@
if (canCut()) {
info.addAction(AccessibilityNodeInfo.ACTION_CUT);
}
+ if (canShare()) {
+ info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
+ ACCESSIBILITY_ACTION_SHARE,
+ getResources().getString(com.android.internal.R.string.share)));
+ }
}
// Check for known input filter types.
@@ -8897,30 +8929,28 @@
}
} return false;
case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
- if (isFocused() && canSelectText()) {
- ensureIterableTextForAccessibilitySelectable();
- CharSequence text = getIterableTextForAccessibility();
- if (text == null) {
- return false;
+ ensureIterableTextForAccessibilitySelectable();
+ CharSequence text = getIterableTextForAccessibility();
+ if (text == null) {
+ return false;
+ }
+ final int start = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+ final int end = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+ if ((getSelectionStart() != start || getSelectionEnd() != end)) {
+ // No arguments clears the selection.
+ if (start == end && end == -1) {
+ Selection.removeSelection((Spannable) text);
+ return true;
}
- final int start = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
- final int end = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
- if ((getSelectionStart() != start || getSelectionEnd() != end)) {
- // No arguments clears the selection.
- if (start == end && end == -1) {
- Selection.removeSelection((Spannable) text);
- return true;
+ if (start >= 0 && start <= end && end <= text.length()) {
+ Selection.setSelection((Spannable) text, start, end);
+ // Make sure selection mode is engaged.
+ if (mEditor != null) {
+ mEditor.startSelectionActionMode();
}
- if (start >= 0 && start <= end && end <= text.length()) {
- Selection.setSelection((Spannable) text, start, end);
- // Make sure selection mode is engaged.
- if (mEditor != null) {
- mEditor.startSelectionActionMode();
- }
- return true;
- }
+ return true;
}
}
} return false;
@@ -8929,6 +8959,13 @@
ensureIterableTextForAccessibilitySelectable();
return super.performAccessibilityActionInternal(action, arguments);
}
+ case ACCESSIBILITY_ACTION_SHARE: {
+ if (isFocused() && canShare()) {
+ if (onTextContextMenuItem(ID_SHARE)) {
+ return true;
+ }
+ }
+ } return false;
default: {
return super.performAccessibilityActionInternal(action, arguments);
}
@@ -9434,10 +9471,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();
+ }
}
}
@@ -9633,7 +9672,8 @@
// since we are doing so explicitlty by other means and these
// controllers interact with how selection behaves.
if (mEditor != null) {
- mEditor.hideControllers();
+ mEditor.hideCursorAndSpanControllers();
+ mEditor.stopTextActionMode();
}
CharSequence text = getIterableTextForAccessibility();
if (Math.min(start, end) >= 0 && Math.max(start, end) <= text.length()) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c1ec6e6..1b55557 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -50,11 +50,13 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import com.android.internal.R;
+import com.android.internal.logging.MetricsLogger;
import java.util.ArrayList;
import java.util.List;
@@ -98,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:
@@ -105,6 +111,7 @@
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
unbindRemainingServices();
+ sendVoiceChoicesIfNeeded();
break;
default:
@@ -185,6 +192,8 @@
setSafeForwardingMode(true);
super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
null, false);
+
+ MetricsLogger.action(this, MetricsLogger.ACTION_ACTIVITY_CHOOSER_SHOWN);
}
@Override
@@ -291,6 +300,36 @@
return super.onTargetSelected(target, alwaysCheck);
}
+ @Override
+ void startSelected(int which, boolean always, boolean filtered) {
+ super.startSelected(which, always, filtered);
+
+ if (mChooserListAdapter != null) {
+ // Log the index of which type of target the user picked.
+ // Lower values mean the ranking was better.
+ int cat = 0;
+ int value = which;
+ switch (mChooserListAdapter.getPositionTargetType(which)) {
+ case ChooserListAdapter.TARGET_CALLER:
+ cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
+ break;
+ case ChooserListAdapter.TARGET_SERVICE:
+ cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET;
+ value -= mChooserListAdapter.getCallerTargetCount();
+ break;
+ case ChooserListAdapter.TARGET_STANDARD:
+ cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET;
+ value -= mChooserListAdapter.getCallerTargetCount()
+ + mChooserListAdapter.getServiceTargetCount();
+ break;
+ }
+
+ if (cat != 0) {
+ MetricsLogger.action(this, cat, value);
+ }
+ }
+ }
+
void queryTargetServices(ChooserListAdapter adapter) {
final PackageManager pm = getPackageManager();
int targetsToQuery = 0;
@@ -350,6 +389,8 @@
+ WATCHDOG_TIMEOUT_MILLIS + "ms");
mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
WATCHDOG_TIMEOUT_MILLIS);
+ } else {
+ sendVoiceChoicesIfNeeded();
}
}
@@ -384,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();
@@ -613,15 +658,17 @@
ri.activityInfo = ai;
UserManager userManager =
(UserManager) getSystemService(Context.USER_SERVICE);
- if (userManager.isManagedProfile()) {
- ri.noResourceId = true;
- }
if (ii instanceof LabeledIntent) {
LabeledIntent li = (LabeledIntent)ii;
ri.resolvePackageName = li.getSourcePackage();
ri.labelRes = li.getLabelResource();
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
ri.icon = li.getIconResource();
+ ri.iconResourceId = ri.icon;
+ }
+ if (userManager.isManagedProfile()) {
+ ri.noResourceId = true;
+ ri.icon = 0;
}
mCallerTargets.add(new DisplayResolveInfo(ii, ri,
ri.loadLabel(pm), null, ii));
@@ -849,6 +896,14 @@
startSelected(itemIndex, false, true);
}
});
+ v.setOnLongClickListener(new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ showAppDetails(
+ mChooserListAdapter.resolveInfoForPosition(itemIndex, true));
+ return true;
+ }
+ });
} else {
v.setVisibility(View.GONE);
}
@@ -912,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/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 929cacd..6f0cec6 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -116,7 +116,7 @@
void noteWifiRadioPowerState(int powerState, long timestampNs);
void noteNetworkInterfaceType(String iface, int type);
void noteNetworkStatsEnabled();
- void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion);
+ void noteDeviceIdleMode(boolean enabled, String activeReason, int activeUid);
void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
long getAwakeTimeBattery();
long getAwakeTimePlugged();
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index b0e0373..4a468be 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -18,7 +18,7 @@
import com.android.internal.R;
-import android.app.Dialog;
+import android.app.AlertDialog;
import android.app.MediaRouteActionProvider;
import android.app.MediaRouteButton;
import android.content.Context;
@@ -46,7 +46,7 @@
*
* TODO: Move this back into the API, as in the support library media router.
*/
-public class MediaRouteControllerDialog extends Dialog {
+public class MediaRouteControllerDialog extends AlertDialog {
// Time to wait before updating the volume when the user lets go of the seek bar
// to allow the route provider time to propagate the change and publish a new
// route descriptor.
@@ -134,8 +134,6 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
-
setContentView(R.layout.media_route_controller_dialog);
mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 39c86f9..e5ff51c 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;
@@ -67,6 +74,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -96,6 +104,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 +251,9 @@
finish();
}
});
+ if (isVoiceInteraction()) {
+ rdl.setCollapsed(false);
+ }
}
if (title == null) {
@@ -313,6 +325,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 +518,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 +563,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;
@@ -819,6 +868,16 @@
}
}
+ /**
+ * Check a simple match for the component of two ResolveInfos.
+ */
+ static boolean resolveInfoMatch(ResolveInfo lhs, ResolveInfo rhs) {
+ return lhs == null ? rhs == null
+ : lhs.activityInfo == null ? rhs.activityInfo == null
+ : Objects.equals(lhs.activityInfo.name, rhs.activityInfo.name)
+ && Objects.equals(lhs.activityInfo.packageName, rhs.activityInfo.packageName);
+ }
+
final class DisplayResolveInfo implements TargetInfo {
private final ResolveInfo mResolveInfo;
private final CharSequence mDisplayLabel;
@@ -1186,15 +1245,17 @@
ri.activityInfo = ai;
UserManager userManager =
(UserManager) getSystemService(Context.USER_SERVICE);
- if (userManager.isManagedProfile()) {
- ri.noResourceId = true;
- }
if (ii instanceof LabeledIntent) {
LabeledIntent li = (LabeledIntent)ii;
ri.resolvePackageName = li.getSourcePackage();
ri.labelRes = li.getLabelResource();
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
ri.icon = li.getIconResource();
+ ri.iconResourceId = ri.icon;
+ }
+ if (userManager.isManagedProfile()) {
+ ri.noResourceId = true;
+ ri.icon = 0;
}
addResolveInfo(new DisplayResolveInfo(ii, ri,
ri.loadLabel(getPackageManager()), null, ii));
@@ -1412,7 +1473,7 @@
public boolean hasResolvedTarget(ResolveInfo info) {
for (int i = 0, N = mDisplayList.size(); i < N; i++) {
- if (info.equals(mDisplayList.get(i).getResolveInfo())) {
+ if (resolveInfoMatch(info, mDisplayList.get(i).getResolveInfo())) {
return true;
}
}
@@ -1642,4 +1703,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..742173b 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");
@@ -1283,4 +1302,131 @@
return enabledInputMethodAndSubtypes;
}
}
+
+ // For spell checker service manager.
+ // TODO: Should we have TextServicesUtils.java?
+ private static final Locale LOCALE_EN_US = new Locale("en", "US");
+ private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
+
+ /**
+ * Returns a list of {@link Locale} in the order of appropriateness for the default spell
+ * checker service.
+ *
+ * <p>If the system language is English, and the region is also explicitly specified in the
+ * system locale, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * <p>If the system language is English, but no region is specified in the system locale,
+ * the following fallback order will be applied.</p>
+ * <ul>
+ * <li>("en")</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * </ul>
+ *
+ * <p>If the system language is not English, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region) (if exists)</li>
+ * <li>(system-locale-language) (if exists)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * @param systemLocale the current system locale to be taken into consideration.
+ * @return a list of {@link Locale}. The first one is considered to be most appropriate.
+ */
+ @VisibleForTesting
+ public static ArrayList<Locale> getSuitableLocalesForSpellChecker(
+ @Nullable final Locale systemLocale) {
+ final Locale systemLocaleLanguageCountryVariant;
+ final Locale systemLocaleLanguageCountry;
+ final Locale systemLocaleLanguage;
+ if (systemLocale != null) {
+ final String language = systemLocale.getLanguage();
+ final boolean hasLanguage = !TextUtils.isEmpty(language);
+ final String country = systemLocale.getCountry();
+ final boolean hasCountry = !TextUtils.isEmpty(country);
+ final String variant = systemLocale.getVariant();
+ final boolean hasVariant = !TextUtils.isEmpty(variant);
+ if (hasLanguage && hasCountry && hasVariant) {
+ systemLocaleLanguageCountryVariant = new Locale(language, country, variant);
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ }
+ if (hasLanguage && hasCountry) {
+ systemLocaleLanguageCountry = new Locale(language, country);
+ } else {
+ systemLocaleLanguageCountry = null;
+ }
+ if (hasLanguage) {
+ systemLocaleLanguage = new Locale(language);
+ } else {
+ systemLocaleLanguage = null;
+ }
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ systemLocaleLanguageCountry = null;
+ systemLocaleLanguage = null;
+ }
+
+ final ArrayList<Locale> locales = new ArrayList<>();
+ if (systemLocaleLanguageCountryVariant != null) {
+ locales.add(systemLocaleLanguageCountryVariant);
+ }
+
+ if (Locale.ENGLISH.equals(systemLocaleLanguage)) {
+ if (systemLocaleLanguageCountry != null) {
+ // If the system language is English, and the region is also explicitly specified,
+ // following fallback order will be applied.
+ // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null]
+ // - en_US [if systemLocaleLanguageCountry is non-null and not en_US]
+ // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB]
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (!LOCALE_EN_US.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_US);
+ }
+ if (!LOCALE_EN_GB.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_GB);
+ }
+ locales.add(Locale.ENGLISH);
+ } else {
+ // If the system language is English, but no region is specified, following
+ // fallback order will be applied.
+ // - en
+ // - en_US
+ // - en_GB
+ locales.add(Locale.ENGLISH);
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ }
+ } else {
+ // If the system language is not English, the fallback order will be
+ // - systemLocaleLanguageCountry [if non-null]
+ // - systemLocaleLanguage [if non-null]
+ // - en_US
+ // - en_GB
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (systemLocaleLanguage != null) {
+ locales.add(systemLocaleLanguage);
+ }
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ locales.add(Locale.ENGLISH);
+ }
+ return locales;
+ }
}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 03f2e3a..263e522 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -33,6 +33,17 @@
public static final int ACTION_VOLUME_KEY = 211;
public static final int ACTION_VOLUME_ICON = 212;
public static final int ACTION_RINGER_MODE = 213;
+ public static final int ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
+ 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;
+ public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
+ public static final int DREAMING = 222;
+ public static final int DOZING = 223;
+
// 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/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 6a85afb..264b8c1 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -480,6 +480,7 @@
final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null);
mStatsPeriod = mTypeBatteryRealtime;
+ BatterySipper osSipper = null;
final SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
@@ -526,15 +527,19 @@
}
if (uid == 0) {
- // The device has probably been awake for longer than the screen on
- // time and application wake lock time would account for. Assign
- // this remainder to the OS, if possible.
- mWakelockPowerCalculator.calculateRemaining(app, mStats, mRawRealtime,
- mRawUptime, mStatsType);
- app.sumPower();
+ osSipper = app;
}
}
}
+
+ if (osSipper != null) {
+ // The device has probably been awake for longer than the screen on
+ // time and application wake lock time would account for. Assign
+ // this remainder to the OS, if possible.
+ mWakelockPowerCalculator.calculateRemaining(osSipper, mStats, mRawRealtime,
+ mRawUptime, mStatsType);
+ osSipper.sumPower();
+ }
}
private void addPhoneUsage() {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 07d1fc8..1bd821d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -95,7 +95,8 @@
public final class BatteryStatsImpl extends BatteryStats {
private static final String TAG = "BatteryStatsImpl";
private static final boolean DEBUG = false;
- private static final boolean DEBUG_ENERGY = false;
+ public static final boolean DEBUG_ENERGY = false;
+ private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY || false;
private static final boolean DEBUG_HISTORY = false;
private static final boolean USE_OLD_HISTORY = false; // for debugging.
@@ -105,7 +106,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 127 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 129 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -151,6 +152,9 @@
BatteryCallback cb = mCallback;
switch (msg.what) {
case MSG_UPDATE_WAKELOCKS:
+ synchronized (BatteryStatsImpl.this) {
+ updateCpuTimeLocked();
+ }
if (cb != null) {
cb.batteryNeedsCpuUpdate();
}
@@ -178,6 +182,7 @@
public interface ExternalStatsSync {
void scheduleSync(String reason);
+ void scheduleWifiSync(String reason);
}
public final MyHandler mHandler;
@@ -203,6 +208,7 @@
final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mWindowTimers = 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<>();
@@ -2503,12 +2509,11 @@
boolean unpluggedScreenOff = unplugged && screenOff;
if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
updateKernelWakelocksLocked();
- requestWakelockCpuUpdate();
- if (!unpluggedScreenOff) {
- // We are switching to no longer tracking wake locks, but we want
- // the next CPU update we receive to take them in to account.
- mDistributeWakelockCpu = true;
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because screen is now " +
+ (unpluggedScreenOff ? "off" : "on"));
}
+ updateCpuTimeLocked();
mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
}
}
@@ -2772,10 +2777,14 @@
mWakeLockNesting++;
}
if (uid >= 0) {
- //if (uid == 0) {
- // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
- //}
- requestWakelockCpuUpdate();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ // We only update the cpu time when a wake lock is acquired if the screen is off.
+ // If the screen is on, we don't distribute the power amongst partial wakelocks.
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because of +wake_lock");
+ }
+ requestWakelockCpuUpdate();
+ }
getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
}
}
@@ -2805,7 +2814,12 @@
}
}
if (uid >= 0) {
- requestWakelockCpuUpdate();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Updating cpu time because of -wake_lock");
+ }
+ requestWakelockCpuUpdate();
+ }
getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
}
}
@@ -2874,46 +2888,14 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
}
- public int startAddingCpuLocked() {
+ public boolean startAddingCpuLocked() {
mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
-
- if (!mOnBatteryInternal) {
- return -1;
- }
-
- final int N = mPartialTimers.size();
- if (N == 0) {
- mLastPartialTimers.clear();
- mDistributeWakelockCpu = false;
- return 0;
- }
-
- if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
- return 0;
- }
-
- mDistributeWakelockCpu = false;
-
- // How many timers should consume CPU? Only want to include ones
- // that have already been in the list.
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- // We don't include the system UID, because it so often
- // holds wake locks at one request or another of an app.
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- return 50;
- }
- }
- }
-
- return 0;
+ return mOnBatteryInternal;
}
- public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
- int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
- int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime) {
+ public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
+ int statSystemTime, int statIOWaitTime, int statIrqTime,
+ int statSoftIrqTime, int statIdleTime) {
if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
+ " user=" + statUserTime + " sys=" + statSystemTime
+ " io=" + statIOWaitTime + " irq=" + statIrqTime
@@ -2926,70 +2908,6 @@
mCurStepStatIrqTime += statIrqTime;
mCurStepStatSoftIrqTime += statSoftIrqTime;
mCurStepStatIdleTime += statIdleTime;
-
- final int N = mPartialTimers.size();
- if (perc != 0) {
- int num = 0;
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- // We don't include the system UID, because it so often
- // holds wake locks at one request or another of an app.
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- num++;
- }
- }
- }
- if (num != 0) {
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- if (st.mInList) {
- Uid uid = st.mUid;
- if (uid != null && uid.mUid != Process.SYSTEM_UID) {
- int myUTime = remainUTime/num;
- int mySTime = remainSTtime/num;
- remainUTime -= myUTime;
- remainSTtime -= mySTime;
- num--;
- Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
- proc.addCpuTimeLocked(myUTime, mySTime);
- }
- }
- }
- }
-
- // Just in case, collect any lost CPU time.
- if (remainUTime != 0 || remainSTtime != 0) {
- Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
- if (uid != null) {
- Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
- proc.addCpuTimeLocked(remainUTime, remainSTtime);
- }
- }
- }
-
- final int NL = mLastPartialTimers.size();
- boolean diff = N != NL;
- for (int i=0; i<NL && !diff; i++) {
- diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
- }
- if (!diff) {
- for (int i=0; i<NL; i++) {
- mPartialTimers.get(i).mInList = true;
- }
- return;
- }
-
- for (int i=0; i<NL; i++) {
- mLastPartialTimers.get(i).mInList = false;
- }
- mLastPartialTimers.clear();
- for (int i=0; i<N; i++) {
- StopwatchTimer st = mPartialTimers.get(i);
- st.mInList = true;
- mLastPartialTimers.add(st);
- }
}
public void noteProcessDiedLocked(int uid, int pid) {
@@ -3271,11 +3189,11 @@
}
}
- public void noteDeviceIdleModeLocked(boolean enabled, boolean fromActive, boolean fromMotion) {
+ public void noteDeviceIdleModeLocked(boolean enabled, String activeReason, int activeUid) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
boolean nowIdling = enabled;
- if (mDeviceIdling && !enabled && !fromActive && !fromMotion) {
+ if (mDeviceIdling && !enabled && activeReason == null) {
// We don't go out of general idling mode until explicitly taken out of
// device idle through going active or significant motion.
nowIdling = true;
@@ -3293,14 +3211,8 @@
}
if (mDeviceIdleModeEnabled != enabled) {
mDeviceIdleModeEnabled = enabled;
- if (fromMotion) {
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SIGNIFICANT_MOTION,
- "", 0);
- }
- if (fromActive) {
- addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
- "", 0);
- }
+ addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
+ activeReason != null ? activeReason : "", activeUid);
if (enabled) {
mHistoryCur.states2 |= HistoryItem.STATE2_DEVICE_IDLE_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode enabled to: "
@@ -3580,7 +3492,7 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = true;
mWifiOnTimer.startRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-off");
+ scheduleSyncExternalWifiStatsLocked("wifi-off");
}
}
@@ -3594,7 +3506,7 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-on");
+ scheduleSyncExternalWifiStatsLocked("wifi-on");
}
}
@@ -3846,7 +3758,7 @@
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
}
- scheduleSyncExternalStatsLocked("wifi-running");
+ scheduleSyncExternalWifiStatsLocked("wifi-running");
} else {
Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
}
@@ -3885,7 +3797,7 @@
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
}
- scheduleSyncExternalStatsLocked("wifi-stopped");
+ scheduleSyncExternalWifiStatsLocked("wifi-stopped");
} else {
Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
}
@@ -3900,7 +3812,7 @@
}
mWifiState = wifiState;
mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-state");
+ scheduleSyncExternalWifiStatsLocked("wifi-state");
}
}
@@ -5737,6 +5649,11 @@
StopwatchTimer mTimerWindow;
/**
+ * How long (in ms) this uid has had a draw wake lock.
+ */
+ StopwatchTimer mTimerDraw;
+
+ /**
* Reads a possibly null Timer from a Parcel. The timer is associated with the
* proper timer pool from the given BatteryStatsImpl object.
*
@@ -5763,6 +5680,9 @@
if (mTimerWindow != null) {
wlactive |= !mTimerWindow.reset(false);
}
+ if (mTimerDraw != null) {
+ wlactive |= !mTimerDraw.reset(false);
+ }
if (!wlactive) {
if (mTimerFull != null) {
mTimerFull.detach();
@@ -5776,6 +5696,10 @@
mTimerWindow.detach();
mTimerWindow = null;
}
+ if (mTimerDraw != null) {
+ mTimerDraw.detach();
+ mTimerDraw = null;
+ }
}
return !wlactive;
}
@@ -5783,16 +5707,16 @@
void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
mPartialTimers, screenOffTimeBase, in);
- mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
- mFullTimers, timeBase, in);
- mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
- mWindowTimers, timeBase, in);
+ mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, mFullTimers, timeBase, in);
+ mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, mWindowTimers, 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, mTimerDraw, elapsedRealtimeUs);
}
@Override
@@ -5801,6 +5725,7 @@
case WAKE_TYPE_FULL: return mTimerFull;
case WAKE_TYPE_PARTIAL: return mTimerPartial;
case WAKE_TYPE_WINDOW: return mTimerWindow;
+ case WAKE_TYPE_DRAW: return mTimerDraw;
default: throw new IllegalArgumentException("type = " + type);
}
}
@@ -5832,6 +5757,14 @@
mTimerWindow = t;
}
return t;
+ case WAKE_TYPE_DRAW:
+ t = mTimerDraw;
+ if (t == null) {
+ t = new StopwatchTimer(Uid.this, WAKE_TYPE_DRAW,
+ mDrawTimers, mOnBatteryTimeBase);
+ mTimerDraw = t;
+ }
+ return t;
default:
throw new IllegalArgumentException("type=" + type);
}
@@ -6688,6 +6621,9 @@
if (in.readInt() != 0) {
wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
}
+ if (in.readInt() != 0) {
+ wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
+ }
}
public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
@@ -7632,6 +7568,10 @@
* @param info The energy information from the WiFi controller.
*/
public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating wifi stats");
+ }
+
final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
NetworkStats delta = null;
try {
@@ -7829,6 +7769,10 @@
* Distribute Cell radio energy info and network traffic to apps.
*/
public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating mobile radio stats");
+ }
+
NetworkStats delta = null;
try {
if (!ArrayUtils.isEmpty(mMobileIfaces)) {
@@ -7901,6 +7845,10 @@
* @param info The energy information from the bluetooth controller.
*/
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating bluetooth stats");
+ }
+
if (info != null && mOnBatteryInternal) {
mHasBluetoothEnergyReporting = true;
mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
@@ -7959,30 +7907,196 @@
}
}
+ // We use an anonymous class to access these variables,
+ // so they can't live on the stack or they'd have to be
+ // final MutableLong objects (more allocations).
+ // Used in updateCpuTimeLocked().
+ long mTempTotalCpuUserTimeUs;
+ long mTempTotalCpuSystemTimeUs;
+
/**
- * Read and distribute CPU usage across apps.
+ * Read and distribute CPU usage across apps. If their are partial wakelocks being held
+ * and we are on battery with screen off, we give more of the cpu time to those apps holding
+ * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
*/
- public void updateCpuTimeLocked(boolean firstTime) {
+ public void updateCpuTimeLocked() {
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "!Cpu updating!");
+ }
+
+ // Holding a wakelock costs more than just using the cpu.
+ // Currently, we assign only half the cpu time to an app that is running but
+ // not holding a wakelock. The apps holding wakelocks get the rest of the blame.
+ // If no app is holding a wakelock, then the distribution is normal.
+ final int wakelockWeight = 50;
+
+ // Read the time spent at various cpu frequencies.
final int cpuSpeedSteps = getCpuSpeedSteps();
final long[] cpuSpeeds = mKernelCpuSpeedReader.readDelta();
- KernelUidCpuTimeReader.Callback callback = null;
- if (mOnBatteryInternal && !firstTime) {
- callback = new KernelUidCpuTimeReader.Callback() {
- @Override
- public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
- final Uid u = getUidStatsLocked(mapUid(uid));
- u.mUserCpuTime.addCountLocked(userTimeUs);
- u.mSystemCpuTime.addCountLocked(systemTimeUs);
- for (int i = 0; i < cpuSpeedSteps; i++) {
- if (u.mSpeedBins[i] == null) {
- u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
- }
- u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
- }
+
+ int numWakelocks = 0;
+
+ // Calculate how many wakelocks we have to distribute amongst. The system is excluded.
+ // Only distribute cpu power to wakelocks if the screen is off and we're on battery.
+ final int numPartialTimers = mPartialTimers.size();
+ if (mOnBatteryScreenOffTimeBase.isRunning()) {
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+ if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
+ // Since the collection and blaming of wakelocks can be scheduled to run after
+ // some delay, the mPartialTimers list may have new entries. We can't blame
+ // the newly added timer for past cpu time, so we only consider timers that
+ // were present for one round of collection. Once a timer has gone through
+ // a round of collection, its mInList field is set to true.
+ numWakelocks++;
}
- };
+ }
}
- mKernelUidCpuTimeReader.readDelta(callback);
+
+ final int numWakelocksF = numWakelocks;
+ mTempTotalCpuUserTimeUs = 0;
+ mTempTotalCpuSystemTimeUs = 0;
+
+ // Read the CPU data for each UID. This will internally generate a snapshot so next time
+ // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise
+ // we just ignore the data.
+ final long startTimeMs = SystemClock.elapsedRealtime();
+ mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
+ new KernelUidCpuTimeReader.Callback() {
+ @Override
+ public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
+ final Uid u = getUidStatsLocked(mapUid(uid));
+
+ // Accumulate the total system and user time.
+ mTempTotalCpuUserTimeUs += userTimeUs;
+ mTempTotalCpuSystemTimeUs += systemTimeUs;
+
+ StringBuilder sb = null;
+ if (DEBUG_ENERGY_CPU) {
+ sb = new StringBuilder();
+ sb.append(" got time for uid=").append(u.mUid).append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ sb.append("\n");
+ }
+
+ if (numWakelocksF > 0) {
+ // We have wakelocks being held, so only give a portion of the
+ // time to the process. The rest will be distributed among wakelock
+ // holders.
+ userTimeUs = (userTimeUs * wakelockWeight) / 100;
+ systemTimeUs = (systemTimeUs * wakelockWeight) / 100;
+ }
+
+ if (sb != null) {
+ sb.append(" adding to uid=").append(u.mUid).append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ u.mUserCpuTime.addCountLocked(userTimeUs);
+ u.mSystemCpuTime.addCountLocked(systemTimeUs);
+
+ // Add the cpu speeds to this UID. These are used as a ratio
+ // for computing the power this UID used.
+ for (int i = 0; i < cpuSpeedSteps; i++) {
+ if (u.mSpeedBins[i] == null) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ }
+ u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
+ }
+ }
+ });
+
+ if (DEBUG_ENERGY_CPU) {
+ Slog.d(TAG, "Reading cpu stats took " + (SystemClock.elapsedRealtime() - startTimeMs) +
+ " ms");
+ }
+
+ if (mOnBatteryInternal && numWakelocks > 0) {
+ // Distribute a portion of the total cpu time to wakelock holders.
+ mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100;
+ mTempTotalCpuSystemTimeUs =
+ (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100;
+
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+
+ // The system does not share any blame, as it is usually holding the wakelock
+ // on behalf of an app.
+ if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
+ int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks);
+ int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks);
+
+ if (DEBUG_ENERGY_CPU) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
+ .append(": u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ timer.mUid.mUserCpuTime.addCountLocked(userTimeUs);
+ timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs);
+
+ final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
+ proc.addCpuTimeLocked(userTimeUs, systemTimeUs);
+
+ mTempTotalCpuUserTimeUs -= userTimeUs;
+ mTempTotalCpuSystemTimeUs -= systemTimeUs;
+ numWakelocks--;
+ }
+ }
+
+ if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) {
+ // Anything left over is given to the system.
+ if (DEBUG_ENERGY_CPU) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" Distributing lost time to system: u=");
+ TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb);
+ sb.append(" s=");
+ TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb);
+ Slog.d(TAG, sb.toString());
+ }
+
+ final Uid u = getUidStatsLocked(Process.SYSTEM_UID);
+ u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs);
+ u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs);
+
+ final Uid.Proc proc = u.getProcessStatsLocked("*lost*");
+ proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs,
+ (int) mTempTotalCpuSystemTimeUs);
+ }
+ }
+
+ // See if there is a difference in wakelocks between this collection and the last
+ // collection.
+ if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
+ // No difference, so each timer is now considered for the next collection.
+ for (int i = 0; i < numPartialTimers; i++) {
+ mPartialTimers.get(i).mInList = true;
+ }
+ } else {
+ // The lists are different, meaning we added (or removed a timer) since the last
+ // collection.
+ final int numLastPartialTimers = mLastPartialTimers.size();
+ for (int i = 0; i < numLastPartialTimers; i++) {
+ mLastPartialTimers.get(i).mInList = false;
+ }
+ mLastPartialTimers.clear();
+
+ // Mark the current timers as gone through a collection.
+ for (int i = 0; i < numPartialTimers; i++) {
+ final StopwatchTimer timer = mPartialTimers.get(i);
+ timer.mInList = true;
+ mLastPartialTimers.add(timer);
+ }
+ }
}
boolean setChargingLocked(boolean charging) {
@@ -8157,6 +8271,12 @@
}
}
+ private void scheduleSyncExternalWifiStatsLocked(String reason) {
+ if (mExternalSync != null) {
+ mExternalSync.scheduleWifiSync(reason);
+ }
+ }
+
// This should probably be exposed in the API, though it's not critical
public static final int BATTERY_PLUGGED_NONE = 0;
@@ -9491,6 +9611,12 @@
} else {
out.writeInt(0);
}
+ if (wl.mTimerDraw != null) {
+ out.writeInt(1);
+ wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
}
final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap();
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index 671bf24..dcc6a5e 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -18,6 +18,7 @@
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
+import android.os.SystemClock;
import android.util.Slog;
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -206,4 +207,14 @@
}
return true;
}
+
+ public void waitForConnection() {
+ for (;;) {
+ if (execute("ping") >= 0) {
+ return;
+ }
+ Slog.w(TAG, "installd not ready");
+ SystemClock.sleep(1000);
+ }
+ }
}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index b236378..41efd2c 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -16,9 +16,11 @@
package com.android.internal.os;
import android.annotation.Nullable;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseLongArray;
+import android.util.TimeUtils;
import java.io.BufferedReader;
import java.io.FileReader;
@@ -49,6 +51,7 @@
private SparseLongArray mLastUserTimeUs = new SparseLongArray();
private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
+ private long mLastTimeReadUs = 0;
/**
* Reads the proc file, calling into the callback with a delta of time for each UID.
@@ -57,6 +60,7 @@
* a fresh delta.
*/
public void readDelta(@Nullable Callback callback) {
+ long nowUs = SystemClock.elapsedRealtime() * 1000;
try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
String line;
@@ -75,10 +79,32 @@
userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
- if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0) {
- // The UID must have been removed from accounting, then added back.
- userTimeDeltaUs = userTimeUs;
- systemTimeDeltaUs = systemTimeUs;
+ final long timeDiffUs = nowUs - mLastTimeReadUs;
+ if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 ||
+ userTimeDeltaUs > timeDiffUs || systemTimeDeltaUs > timeDiffUs) {
+ StringBuilder sb = new StringBuilder("Malformed cpu data!\n");
+ sb.append("Time between reads: ");
+ TimeUtils.formatDuration(timeDiffUs / 1000, sb);
+ sb.append("ms\n");
+ sb.append("Previous times: u=");
+ TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb);
+ sb.append("ms\n");
+ sb.append("Current times: u=");
+ TimeUtils.formatDuration(userTimeUs / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(systemTimeUs / 1000, sb);
+ sb.append("ms\n");
+ sb.append("Delta for UID=").append(uid).append(": u=");
+ TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb);
+ sb.append("ms s=");
+ TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb);
+ sb.append("ms");
+ Slog.wtf(TAG, sb.toString());
+
+ userTimeDeltaUs = 0;
+ systemTimeDeltaUs = 0;
}
}
@@ -92,6 +118,7 @@
} catch (IOException e) {
Slog.e(TAG, "Failed to read uid_cputime", e);
}
+ mLastTimeReadUs = nowUs;
}
/**
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 4f6d781..197004c 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -41,13 +41,17 @@
public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
/** enable the JIT compiler */
public static final int DEBUG_ENABLE_JIT = 1 << 5;
- /** Force generation of CFI code */
- public static final int DEBUG_GENERATE_CFI = 1 << 6;
+ /** Force generation of native debugging information. */
+ public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 6;
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = 0;
- /** Default user-specific external storage should be mounted. */
+ /** Default external storage should be mounted. */
public static final int MOUNT_EXTERNAL_DEFAULT = 1;
+ /** Read-only external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_READ = 2;
+ /** Read-write external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_WRITE = 3;
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 1a0345b..3e86fac 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -322,7 +322,7 @@
/**
* From --enable-debugger, --enable-checkjni, --enable-assert,
- * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging.
+ * --enable-safemode, --enable-jit, --generate-debug-info and --enable-jni-logging.
*/
int debugFlags;
@@ -434,8 +434,8 @@
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
} else if (arg.equals("--enable-jit")) {
debugFlags |= Zygote.DEBUG_ENABLE_JIT;
- } else if (arg.equals("--generate-cfi")) {
- debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+ } else if (arg.equals("--generate-debug-info")) {
+ debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
} else if (arg.equals("--enable-jni-logging")) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
} else if (arg.equals("--enable-assert")) {
@@ -519,6 +519,10 @@
niceName = arg.substring(arg.indexOf('=') + 1);
} else if (arg.equals("--mount-external-default")) {
mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+ } else if (arg.equals("--mount-external-read")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_READ;
+ } else if (arg.equals("--mount-external-write")) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
} else if (arg.equals("--query-abi-list")) {
abiListQuery = true;
} else if (arg.startsWith("--instruction-set=")) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 971da77..06919e1 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -468,6 +468,7 @@
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
final InstallerConnection installer = new InstallerConnection();
+ installer.waitForConnection();
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
try {
diff --git a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
index 1d0511f..0a01ae9 100644
--- a/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
+++ b/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
@@ -17,6 +17,10 @@
/**
* Takes care of unmounting and formatting external storage.
+ *
+ * @deprecated Please use {@link Intent#ACTION_MASTER_CLEAR} broadcast with extra
+ * {@link Intent#EXTRA_WIPE_EXTERNAL_STORAGE} to wipe and factory reset, or call
+ * {@link StorageManager#wipeAdoptableDisks} directly to format external storages.
*/
public class ExternalStorageFormatter extends Service {
static final String TAG = "ExternalStorageFormatter";
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 66f6079..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;
@@ -3223,12 +3226,11 @@
cb.onWindowFocusChanged(hasWindowFocus);
}
- if (mFloatingToolbar != null) {
- if (hasWindowFocus) {
- mFloatingToolbar.show();
- } else {
- mFloatingToolbar.dismiss();
- }
+ if (mPrimaryActionMode != null) {
+ mPrimaryActionMode.onWindowFocusChanged(hasWindowFocus);
+ }
+ if (mFloatingActionMode != null) {
+ mFloatingActionMode.onWindowFocusChanged(hasWindowFocus);
}
}
@@ -3346,6 +3348,7 @@
}
private ActionMode createStandaloneActionMode(ActionMode.Callback callback) {
+ endOnGoingFadeAnimation();
cleanupPrimaryActionMode();
if (mPrimaryActionModeView == null) {
if (isFloating()) {
@@ -3385,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 {
@@ -3405,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);
@@ -3441,8 +3501,7 @@
mFloatingActionMode = mode;
mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this);
((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar);
- mFloatingActionMode.invalidate();
- mFloatingToolbar.show();
+ mFloatingActionMode.invalidate(); // Will show the floating toolbar if necessary.
mFloatingActionModeOriginatingView.getViewTreeObserver()
.addOnPreDrawListener(mFloatingToolbarPreDrawListener);
}
@@ -3475,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/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 9f99f62..0732add 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -64,5 +64,7 @@
* bar caused by this app transition in millis
*/
void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
+
+ void showAssistDisclosure();
}
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/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 62e724a..9d0636a 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -387,4 +387,26 @@
public static <T> boolean contains(ArrayList<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}
+
+ /**
+ * Returns true if the two ArrayLists are equal with respect to the objects they contain.
+ * The objects must be in the same order and be reference equal (== not .equals()).
+ */
+ public static <T> boolean referenceEquals(ArrayList<T> a, ArrayList<T> b) {
+ if (a == b) {
+ return true;
+ }
+
+ final int sizeA = a.size();
+ final int sizeB = b.size();
+ if (a == null || b == null || sizeA != sizeB) {
+ return false;
+ }
+
+ boolean diff = false;
+ for (int i = 0; i < sizeA && !diff; i++) {
+ diff |= a.get(i) != b.get(i);
+ }
+ return !diff;
+ }
}
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 784b256..b2699f8 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -30,6 +30,8 @@
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.FloatingToolbar;
+import java.util.Arrays;
+
public class FloatingActionMode extends ActionMode {
private static final int MAX_HIDE_DURATION = 3000;
@@ -42,7 +44,9 @@
private final Rect mContentRectOnWindow;
private final Rect mPreviousContentRectOnWindow;
private final int[] mViewPosition;
+ private final int[] mPreviousViewPosition;
private final Rect mViewRect;
+ private final Rect mPreviousViewRect;
private final Rect mScreenRect;
private final View mOriginatingView;
private final int mBottomAllowance;
@@ -75,7 +79,9 @@
mContentRectOnWindow = new Rect();
mPreviousContentRectOnWindow = new Rect();
mViewPosition = new int[2];
+ mPreviousViewPosition = new int[2];
mViewRect = new Rect();
+ mPreviousViewRect = new Rect();
mScreenRect = new Rect();
mOriginatingView = Preconditions.checkNotNull(originatingView);
mOriginatingView.getLocationInWindow(mViewPosition);
@@ -129,9 +135,17 @@
public void updateViewLocationInWindow() {
checkToolbarInitialized();
+
mOriginatingView.getLocationInWindow(mViewPosition);
mOriginatingView.getGlobalVisibleRect(mViewRect);
- repositionToolbar();
+
+ if (!Arrays.equals(mViewPosition, mPreviousViewPosition)
+ || !mViewRect.equals(mPreviousViewRect)) {
+ repositionToolbar();
+ mPreviousViewPosition[0] = mViewPosition[0];
+ mPreviousViewPosition[1] = mViewPosition[1];
+ mPreviousViewRect.set(mViewRect);
+ }
}
private void repositionToolbar() {
@@ -153,6 +167,7 @@
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
mFloatingToolbar.setContentRect(mContentRectOnWindow);
@@ -160,9 +175,9 @@
}
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mContentRectOnWindow.setEmpty();
}
- mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
}
@@ -197,6 +212,13 @@
}
@Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ checkToolbarInitialized();
+ mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus);
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
+ }
+
+ @Override
public void finish() {
checkToolbarInitialized();
reset();
@@ -237,6 +259,7 @@
}
private void reset() {
+ mFloatingToolbar.dismiss();
mFloatingToolbarVisibilityHelper.deactivate();
mOriginatingView.removeCallbacks(mMovingOff);
mOriginatingView.removeCallbacks(mHideOff);
@@ -253,6 +276,7 @@
private boolean mHideRequested;
private boolean mMoving;
private boolean mOutOfBounds;
+ private boolean mWindowFocused = true;
private boolean mActive;
@@ -264,6 +288,7 @@
mHideRequested = false;
mMoving = false;
mOutOfBounds = false;
+ mWindowFocused = true;
mActive = true;
}
@@ -285,12 +310,16 @@
mOutOfBounds = outOfBounds;
}
+ public void setWindowFocused(boolean windowFocused) {
+ mWindowFocused = windowFocused;
+ }
+
public void updateToolbarVisibility() {
if (!mActive) {
return;
}
- if (mHideRequested || mMoving || mOutOfBounds) {
+ if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) {
mToolbar.hide();
} else {
mToolbar.show();
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index e19b2b6..85ec29c 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -409,8 +409,8 @@
}
case DO_REPORT_FULLSCREEN_MODE: {
InputConnection ic = mInputConnection.get();
- if (ic == null || !isActive()) {
- Log.w(TAG, "showStatusIcon on inactive InputConnection");
+ if (ic == null) {
+ Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
return;
}
ic.reportFullscreenMode(msg.arg1 == 1);
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/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 65f2f53f..a6e8034 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -23,6 +23,7 @@
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -30,6 +31,7 @@
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.util.Size;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -83,6 +85,7 @@
private final FloatingToolbarPopup mPopup;
private final Rect mContentRect = new Rect();
+ private final Rect mPreviousContentRect = new Rect();
private Menu mMenu;
private List<Object> mShowingMenuItems = new ArrayList<Object>();
@@ -108,8 +111,10 @@
* Initializes a floating toolbar.
*/
public FloatingToolbar(Context context, Window window) {
- mContext = Preconditions.checkNotNull(context);
- mPopup = new FloatingToolbarPopup(window.getDecorView());
+ Preconditions.checkNotNull(context);
+ Preconditions.checkNotNull(window);
+ mContext = applyDefaultTheme(context);
+ mPopup = new FloatingToolbarPopup(mContext, window.getDecorView());
}
/**
@@ -174,11 +179,13 @@
mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
mShowingMenuItems = getShowingMenuItemsReferences(menuItems);
}
- mPopup.updateCoordinates(mContentRect);
if (!mPopup.isShowing()) {
mPopup.show(mContentRect);
+ } else if (!mPreviousContentRect.equals(mContentRect)) {
+ mPopup.updateCoordinates(mContentRect);
}
mWidthChanged = false;
+ mPreviousContentRect.set(mContentRect);
return this;
}
@@ -276,6 +283,7 @@
public static final int OVERFLOW_DIRECTION_UP = 0;
public static final int OVERFLOW_DIRECTION_DOWN = 1;
+ private final Context mContext;
private final View mParent;
private final PopupWindow mPopupWindow;
private final ViewGroup mContentContainer;
@@ -313,24 +321,8 @@
};
private final AnimatorSet mDismissAnimation;
private final AnimatorSet mHideAnimation;
- private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) {
- @Override
- public void cancel() {
- if (hasStarted() && !hasEnded()) {
- super.cancel();
- setOverflowPanelAsContent();
- }
- }
- };
- private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true) {
- @Override
- public void cancel() {
- if (hasStarted() && !hasEnded()) {
- super.cancel();
- setMainPanelAsContent();
- }
- }
- };
+ private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true);
+ private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true);
private final Runnable mOpenOverflow = new Runnable() {
@Override
@@ -375,9 +367,10 @@
* @param parent A parent view to get the {@link android.view.View#getWindowToken()} token
* from.
*/
- public FloatingToolbarPopup(View parent) {
+ public FloatingToolbarPopup(Context context, View parent) {
mParent = Preconditions.checkNotNull(parent);
- mContentContainer = createContentContainer(parent.getContext());
+ mContext = Preconditions.checkNotNull(context);
+ mContentContainer = createContentContainer(context);
mPopupWindow = createPopupWindow(mContentContainer);
mDismissAnimation = createExitAnimation(
mContentContainer,
@@ -415,7 +408,7 @@
mContentContainer.removeAllViews();
if (mMainPanel == null) {
- mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow);
+ mMainPanel = new FloatingToolbarMainPanel(mContext, mOpenOverflow);
}
List<MenuItem> overflowMenuItems =
mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth));
@@ -423,7 +416,7 @@
if (!overflowMenuItems.isEmpty()) {
if (mOverflowPanel == null) {
mOverflowPanel =
- new FloatingToolbarOverflowPanel(mParent.getContext(), mCloseOverflow);
+ new FloatingToolbarOverflowPanel(mContext, mCloseOverflow);
}
mOverflowPanel.setMenuItems(overflowMenuItems);
mOverflowPanel.setOnMenuItemClickListener(menuItemClickListener);
@@ -540,31 +533,31 @@
* Returns the context this popup is running in.
*/
public Context getContext() {
- return mContentContainer.getContext();
+ return mContext;
}
private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
refreshViewPort();
- int availableHeightAboveContent =
- contentRect.top - mViewPort.top - 2 * mMarginVertical;
- int availableHeightBelowContent =
- mViewPort.bottom - contentRect.bottom - 2 * mMarginVertical;
- int availableHeightThroughContent =
- mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
-
int x = contentRect.centerX() - getWidth() / 2;
// Update x so that the toolbar isn't rendered behind the nav bar in landscape.
x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
int y;
+
+ int availableHeightAboveContent = contentRect.top - mViewPort.top;
+ int availableHeightBelowContent = mViewPort.bottom - contentRect.bottom;
+
if (mOverflowPanel == null) { // There is no overflow.
- if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()) {
+ if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()) {
// There is enough space at the top of the content.
y = contentRect.top - getToolbarHeightWithVerticalMargin();
- } else if (availableHeightBelowContent > getToolbarHeightWithVerticalMargin()) {
+ } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
// There is enough space at the bottom of the content.
y = contentRect.bottom;
+ } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) {
+ // Just enough space to fit the toolbar with no vertical margins.
+ y = contentRect.bottom - mMarginVertical;
} else {
// Not enough space. Prefer to position as high as possible.
y = Math.max(
@@ -572,32 +565,47 @@
contentRect.top - getToolbarHeightWithVerticalMargin());
}
} else { // There is an overflow.
- if (availableHeightAboveContent > mOverflowPanel.getMinimumHeight()) {
+ int margin = 2 * mMarginVertical;
+ int minimumOverflowHeightWithMargin = mOverflowPanel.getMinimumHeight() + margin;
+ int availableHeightThroughContentDown =
+ mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
+ int availableHeightThroughContentUp =
+ contentRect.bottom - mViewPort.top + getToolbarHeightWithVerticalMargin();
+
+ if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
// There is enough space at the top of the content rect for the overflow.
// Position above and open upwards.
- updateOverflowHeight(availableHeightAboveContent);
+ updateOverflowHeight(availableHeightAboveContent - margin);
y = contentRect.top - getHeight();
mOverflowDirection = OVERFLOW_DIRECTION_UP;
- } else if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()
- && availableHeightThroughContent > mOverflowPanel.getMinimumHeight()) {
+ } else if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()
+ && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
// There is enough space at the top of the content rect for the main panel
// but not the overflow.
// Position above but open downwards.
- updateOverflowHeight(availableHeightThroughContent);
+ updateOverflowHeight(availableHeightThroughContentDown - margin);
y = contentRect.top - getToolbarHeightWithVerticalMargin();
mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
- } else if (availableHeightBelowContent > mOverflowPanel.getMinimumHeight()) {
+ } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
// There is enough space at the bottom of the content rect for the overflow.
// Position below and open downwards.
- updateOverflowHeight(availableHeightBelowContent);
+ updateOverflowHeight(availableHeightBelowContent - margin);
y = contentRect.bottom;
mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
+ } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()
+ && mViewPort.height() >= minimumOverflowHeightWithMargin) {
+ // There is enough space at the bottom of the content rect for the main panel
+ // but not the overflow.
+ // Position below but open upwards.
+ updateOverflowHeight(availableHeightThroughContentUp - margin);
+ y = contentRect.bottom + getToolbarHeightWithVerticalMargin() - getHeight();
+ mOverflowDirection = OVERFLOW_DIRECTION_UP;
} else {
// Not enough space.
- // Position at the bottom of the view port and open upwards.
- updateOverflowHeight(mViewPort.height());
- y = mViewPort.bottom - getHeight();
- mOverflowDirection = OVERFLOW_DIRECTION_UP;
+ // Position at the top of the view port and open downwards.
+ updateOverflowHeight(mViewPort.height() - margin);
+ y = mViewPort.top;
+ mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
}
mOverflowPanel.setOverflowDirection(mOverflowDirection);
}
@@ -606,7 +614,7 @@
}
private int getToolbarHeightWithVerticalMargin() {
- return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2;
+ return getEstimatedToolbarHeight(mContext) + mMarginVertical * 2;
}
/**
@@ -636,8 +644,24 @@
}
private void cancelOverflowAnimations() {
- mOpenOverflowAnimation.cancel();
- mCloseOverflowAnimation.cancel();
+ if (mOpenOverflowAnimation.hasStarted()
+ && !mOpenOverflowAnimation.hasEnded()) {
+ // Remove the animation listener, stop the animation,
+ // then trigger the lister explicitly so it is not posted
+ // to the message queue.
+ mOpenOverflowAnimation.setAnimationListener(null);
+ mContentContainer.clearAnimation();
+ mOnOverflowOpened.onAnimationEnd(null);
+ }
+ if (mCloseOverflowAnimation.hasStarted()
+ && !mCloseOverflowAnimation.hasEnded()) {
+ // Remove the animation listener, stop the animation,
+ // then trigger the lister explicitly so it is not posted
+ // to the message queue.
+ mCloseOverflowAnimation.setAnimationListener(null);
+ mContentContainer.clearAnimation();
+ mOnOverflowClosed.onAnimationEnd(null);
+ }
}
/**
@@ -1111,7 +1135,7 @@
private final Runnable mCloseOverflow;
private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
- private int mOverflowWidth = 0;
+ private int mOverflowWidth;
private int mSuggestedHeight;
/**
@@ -1122,7 +1146,6 @@
*/
public FloatingToolbarOverflowPanel(Context context, Runnable closeOverflow) {
mCloseOverflow = Preconditions.checkNotNull(closeOverflow);
- mSuggestedHeight = getScreenHeight(context);
mContentView = new LinearLayout(context);
mContentView.setOrientation(LinearLayout.VERTICAL);
@@ -1246,7 +1269,8 @@
mListView.setLayoutParams(params);
}
- private int setOverflowWidth() {
+ private void setOverflowWidth() {
+ mOverflowWidth = 0;
for (int i = 0; i < mListView.getAdapter().getCount(); i++) {
MenuItem menuItem = (MenuItem) mListView.getAdapter().getItem(i);
Preconditions.checkNotNull(menuItem);
@@ -1256,7 +1280,6 @@
mOverflowWidth = Math.max(
mListViewItemWidthCalculator.getMeasuredWidth(), mOverflowWidth);
}
- return mOverflowWidth;
}
private ListView createOverflowListView() {
@@ -1422,7 +1445,6 @@
PopupWindow popupWindow = new PopupWindow(popupContentHolder);
popupWindow.setWindowLayoutType(
WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
- popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setAnimationStyle(0);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
content.setLayoutParams(new ViewGroup.LayoutParams(
@@ -1463,6 +1485,17 @@
return animation;
}
+ /**
+ * Returns a re-themed context with controlled look and feel for views.
+ */
+ private static Context applyDefaultTheme(Context originalContext) {
+ TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
+ boolean isLightTheme = a.getBoolean(0, true);
+ int themeId = isLightTheme ? R.style.Theme_Material_Light : R.style.Theme_Material;
+ a.recycle();
+ return new ContextThemeWrapper(originalContext, themeId);
+ }
+
private static int getEstimatedToolbarHeight(Context context) {
return context.getResources().getDimensionPixelSize(R.dimen.floating_toolbar_height);
}
@@ -1471,30 +1504,4 @@
return context.getResources()
.getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width);
}
-
- private static int getAdjustedToolbarWidth(Context context, int width) {
- int maximumWidth = getScreenWidth(context) - 2 * context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
-
- if (width <= 0 || width > maximumWidth) {
- int defaultWidth = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
- width = Math.min(defaultWidth, maximumWidth);
- }
- return width;
- }
-
- /**
- * Returns the device's screen width.
- */
- private static int getScreenWidth(Context context) {
- return context.getResources().getDisplayMetrics().widthPixels;
- }
-
- /**
- * Returns the device's screen height.
- */
- private static int getScreenHeight(Context context) {
- return context.getResources().getDisplayMetrics().heightPixels;
- }
}
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index be727f1..1071e12 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -127,6 +127,8 @@
final ViewConfiguration vc = ViewConfiguration.get(context);
mTouchSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
+
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
public void setSmallCollapsed(boolean smallCollapsed) {
@@ -142,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();
}
@@ -573,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;
@@ -593,11 +609,6 @@
}
@Override
- public CharSequence getAccessibilityClassName() {
- return ResolverDrawerLayout.class.getName();
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
if (isEnabled()) {
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index e76302b..a2c4f6a 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -85,7 +85,7 @@
*/
public class ViewPager extends ViewGroup {
private static final String TAG = "ViewPager";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final int MAX_SCROLL_X = 2 << 23;
private static final boolean USE_CACHE = 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.mk b/core/jni/Android.mk
index faf926c..5e5450e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -16,6 +16,10 @@
LOCAL_CFLAGS += -DPACKED=""
endif
+ifneq ($(ENABLE_CPUSETS),)
+ LOCAL_CFLAGS += -DENABLE_CPUSETS
+endif
+
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -DU_USING_ICU_NAMESPACE=0
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7c2b28d..bffbab7 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -588,6 +588,8 @@
char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
+ char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
+ char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
bool checkJni = false;
property_get("dalvik.vm.checkjni", propBuf, "");
@@ -848,6 +850,24 @@
profileMaxStackDepth,
"-Xprofile-max-stack-depth:");
+ /*
+ * Tracing options.
+ */
+ property_get("dalvik.vm.method-trace", propBuf, "false");
+ if (strcmp(propBuf, "true") == 0) {
+ addOption("-Xmethod-trace");
+ parseRuntimeOption("dalvik.vm.method-trace-file",
+ methodTraceFileBuf,
+ "-Xmethod-trace-file:");
+ parseRuntimeOption("dalvik.vm.method-trace-file-siz",
+ methodTraceFileSizeBuf,
+ "-Xmethod-trace-file-size:");
+ property_get("dalvik.vm.method-trace-stream", propBuf, "false");
+ if (strcmp(propBuf, "true") == 0) {
+ addOption("-Xmethod-trace-stream");
+ }
+ }
+
// Native bridge library. "0" means that native bridge is disabled.
property_get("ro.dalvik.vm.native.bridge", propBuf, "");
if (propBuf[0] == '\0') {
@@ -876,16 +896,16 @@
"-Xzygote-max-boot-retry=");
/*
- * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot
- * image, if it is compiled on device, will include CFI info, as well as other compilations
- * started by the runtime.
+ * When running with debug.generate-debug-info, add --generate-debug-info to
+ * the compiler options so that the boot image, if it is compiled on device,
+ * will include native debugging information.
*/
- property_get("debug.gencfi", propBuf, "");
+ property_get("debug.generate-debug-info", propBuf, "");
if (strcmp(propBuf, "true") == 0) {
addOption("-Xcompiler-option");
- addOption("--include-cfi");
+ addOption("--generate-debug-info");
addOption("-Ximage-compiler-option");
- addOption("--include-cfi");
+ addOption("--generate-debug-info");
}
initArgs.version = JNI_VERSION_1_4;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index d14fc0f..b9fd65f 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -606,7 +606,9 @@
Layout layout;
TypefaceImpl* typeface = getNativeTypeface(env, jpaint);
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray, start, count, textLength);
+ // Only the substring is used for measurement, so no additional context is passed in. This
+ // behavior is consistent between char[] and String specializations.
+ MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, textArray + start, 0, count, count);
width = layout.getAdvance();
env->ReleaseStringChars(text, textArray);
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_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 9f2181f..91b3278 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -856,7 +856,8 @@
bool useInMask;
size_t numPositionMasks = 0;
size_t numIndexMasks = 0;
- size_t numUniqueFormats;
+ size_t numUniqueFormats = 0;
+
ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
@@ -907,12 +908,13 @@
}
// formats
- cFormats = new int[nAudioPort->num_formats];
- numUniqueFormats = 0;
- for (size_t index = 0; index < nAudioPort->num_formats; index++) {
- int format = audioFormatFromNative(nAudioPort->formats[index]);
- if (!hasFormat(cFormats, numUniqueFormats, format)) {
- cFormats[numUniqueFormats++] = format;
+ if (nAudioPort->num_formats != 0) {
+ cFormats = new int[nAudioPort->num_formats];
+ for (size_t index = 0; index < nAudioPort->num_formats; index++) {
+ int format = audioFormatFromNative(nAudioPort->formats[index]);
+ if (!hasFormat(cFormats, numUniqueFormats, format)) {
+ cFormats[numUniqueFormats++] = format;
+ }
}
}
jFormats = env->NewIntArray(numUniqueFormats);
@@ -920,7 +922,9 @@
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
}
- env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
+ if (numUniqueFormats != 0) {
+ env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
+ }
// gains
jGains = env->NewObjectArray(nAudioPort->num_gains,
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 2ee9283..0f5ba83f 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -230,9 +230,11 @@
static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
- const status_t err = parcel->writeInt32(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
+ if (parcel != NULL) {
+ const status_t err = parcel->writeInt32(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
}
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 70a7805..c139cd7 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -682,18 +682,30 @@
break;
case FAILED_TRANSACTION: {
ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
+ const char* exceptionToThrow;
char msg[128];
- snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
// TransactionTooLargeException is a checked exception, only throw from certain methods.
// FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
// but it is not the only one. The Binder driver can return BR_FAILED_REPLY
// for other reasons also, such as if the transaction is malformed or
// refers to an FD that has been closed. We should change the driver
// to enable us to distinguish these cases in the future.
- jniThrowException(env, canThrowRemoteException
- ? "android/os/TransactionTooLargeException"
- : "java/lang/RuntimeException",
- parcelSize > 0 ? msg : NULL);
+ if (canThrowRemoteException && parcelSize > 200*1024) {
+ // bona fide large payload
+ exceptionToThrow = "android/os/TransactionTooLargeException";
+ snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
+ } else {
+ // Heuristic: a payload smaller than this threshold "shouldn't" be too
+ // big, so it's probably some other, more subtle problem. In practice
+ // it seems to always mean that the remote process died while the binder
+ // transaction was already in flight.
+ exceptionToThrow = (canThrowRemoteException)
+ ? "android/os/DeadObjectException"
+ : "java/lang/RuntimeException";
+ snprintf(msg, sizeof(msg)-1,
+ "Transaction failed on small parcel; remote process probably died");
+ }
+ jniThrowException(env, exceptionToThrow, msg);
} break;
case FDS_NOT_ALLOWED:
jniThrowException(env, "java/lang/RuntimeException",
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 2830724..ee8fb19 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -239,7 +239,8 @@
if (t_pri <= ANDROID_PRIORITY_AUDIO) {
int scheduler = sched_getscheduler(t_pid);
if ((scheduler == SCHED_FIFO) || (scheduler == SCHED_RR)) {
- // This task wants to stay in it's current audio group so it can keep it's budget
+ // This task wants to stay in its current audio group so it can keep its budget
+ // don't update its cpuset or cgroup
continue;
}
}
@@ -247,15 +248,33 @@
if (isDefault) {
if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
// This task wants to stay at background
+ // update its cpuset so it doesn't only run on bg core(s)
+#ifdef ENABLE_CPUSETS
+ int err = set_cpuset_policy(t_pid, sp);
+ if (err != NO_ERROR) {
+ signalExceptionForGroupError(env, -err);
+ break;
+ }
+#endif
continue;
}
}
-
- int err = set_sched_policy(t_pid, sp);
+ int err;
+#ifdef ENABLE_CPUSETS
+ // set both cpuset and cgroup for general threads
+ err = set_cpuset_policy(t_pid, sp);
if (err != NO_ERROR) {
signalExceptionForGroupError(env, -err);
break;
}
+#endif
+
+ err = set_sched_policy(t_pid, sp);
+ if (err != NO_ERROR) {
+ signalExceptionForGroupError(env, -err);
+ break;
+ }
+
}
closedir(d);
}
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/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index a526223..daa6f82 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -48,7 +48,6 @@
#define LIB_SUFFIX_LEN (sizeof(LIB_SUFFIX) - 1)
#define RS_BITCODE_SUFFIX ".bc"
-#define RS_BITCODE_SUFFIX_LEN (sizeof(RS_BITCODE_SUFFIX) -1)
#define GDBSERVER "gdbserver"
#define GDBSERVER_LEN (sizeof(GDBSERVER) - 1)
@@ -322,7 +321,8 @@
public:
static NativeLibrariesIterator* create(ZipFileRO* zipFile) {
void* cookie = NULL;
- if (!zipFile->startIteration(&cookie)) {
+ // Do not specify a suffix to find both .so files and gdbserver.
+ if (!zipFile->startIteration(&cookie, APK_LIB, NULL /* suffix */)) {
return NULL;
}
@@ -337,11 +337,6 @@
continue;
}
- // Make sure we're in the lib directory of the ZIP.
- if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
- continue;
- }
-
// Make sure the filename is at least to the minimum library name size.
const size_t fileNameLen = strlen(fileName);
static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN;
@@ -529,7 +524,7 @@
jlong apkHandle) {
ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
void* cookie = NULL;
- if (!zipFile->startIteration(&cookie)) {
+ if (!zipFile->startIteration(&cookie, NULL /* prefix */, RS_BITCODE_SUFFIX)) {
return APK_SCAN_ERROR;
}
@@ -539,12 +534,9 @@
if (zipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
continue;
}
-
- const size_t fileNameLen = strlen(fileName);
const char* lastSlash = strrchr(fileName, '/');
const char* baseName = (lastSlash == NULL) ? fileName : fileName + 1;
- if (!strncmp(fileName + fileNameLen - RS_BITCODE_SUFFIX_LEN, RS_BITCODE_SUFFIX,
- RS_BITCODE_SUFFIX_LEN) && isFilenameSafe(baseName)) {
+ if (isFilenameSafe(baseName)) {
zipFile->endIteration(cookie);
return BITCODE_PRESENT;
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 76db5d3..f7cfe0e 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -66,6 +66,8 @@
enum MountExternalKind {
MOUNT_EXTERNAL_NONE = 0,
MOUNT_EXTERNAL_DEFAULT = 1,
+ MOUNT_EXTERNAL_READ = 2,
+ MOUNT_EXTERNAL_WRITE = 3,
};
static void RuntimeAbort(JNIEnv* env) {
@@ -249,38 +251,49 @@
// Create a private mount namespace and bind mount appropriate emulated
// storage for the given user.
-static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
- if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
+static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
+ bool force_mount_namespace) {
+ // See storage config details at http://source.android.com/tech/storage/
+
+ // Create a second private mount namespace for our process
+ if (unshare(CLONE_NEWNS) == -1) {
+ ALOGW("Failed to unshare(): %s", strerror(errno));
+ return false;
+ }
+
+ // Unmount storage provided by root namespace and mount requested view
+ umount2("/storage", MNT_FORCE);
+
+ String8 storageSource;
+ if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
+ storageSource = "/mnt/runtime_default";
+ } else if (mount_mode == MOUNT_EXTERNAL_READ) {
+ storageSource = "/mnt/runtime_read";
+ } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
+ storageSource = "/mnt/runtime_write";
+ } else {
+ // Sane default of no storage visible
+ return true;
+ }
+ if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
+ NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
+ ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
+ return false;
+ }
+
+ // Mount user-specific symlink helpers into place
+ userid_t user_id = multiuser_get_user_id(uid);
+ const String8 userSource(String8::format("/mnt/user/%d", user_id));
+ if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
+ return false;
+ }
+ if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
+ NULL, MS_BIND, NULL)) == -1) {
+ ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
+ return false;
+ }
+
return true;
- }
-
- // Create a second private mount namespace for our process
- if (unshare(CLONE_NEWNS) == -1) {
- ALOGW("Failed to unshare(): %s", strerror(errno));
- return false;
- }
-
- if (mount_mode == MOUNT_EXTERNAL_NONE) {
- return true;
- }
-
- // See storage config details at http://source.android.com/tech/storage/
- userid_t user_id = multiuser_get_user_id(uid);
-
- // Bind mount user-specific storage into place
- const String8 source(String8::format("/mnt/user/%d", user_id));
- const String8 target(String8::format("/storage/self"));
-
- if (fs_prepare_dir(source.string(), 0755, 0, 0) == -1) {
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(mount(source.string(), target.string(), NULL, MS_BIND, NULL)) == -1) {
- ALOGW("Failed to mount %s to %s: %s", source.string(), target.string(), strerror(errno));
- return false;
- }
-
- return true;
}
static bool NeedsNoRandomizeWorkaround() {
@@ -543,7 +556,7 @@
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
- MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
+ MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f197597..bd9b014 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -242,6 +242,7 @@
<protected-broadcast android:name="android.intent.action.DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN" />
<protected-broadcast android:name="com.android.server.WifiManager.action.START_SCAN" />
+ <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
<protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
<protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
@@ -334,34 +335,24 @@
android:description="@string/permgroupdesc_contacts"
android:priority="100" />
- <!-- Allows an application to read the user's contacts data. -->
+ <!-- Allows an application to read the user's contacts data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CONTACTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:label="@string/permlab_readContacts"
android:description="@string/permdesc_readContacts"
android:protectionLevel="dangerous" />
- <!-- Allows an application to write the user's contacts data. -->
+ <!-- Allows an application to write the user's contacts data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CONTACTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:label="@string/permlab_writeContacts"
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 -->
<!-- ====================================================================== -->
@@ -374,14 +365,18 @@
android:description="@string/permgroupdesc_calendar"
android:priority="200" />
- <!-- Allows an application to read the user's calendar data. -->
+ <!-- Allows an application to read the user's calendar data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CALENDAR"
android:permissionGroup="android.permission-group.CALENDAR"
android:label="@string/permlab_readCalendar"
android:description="@string/permdesc_readCalendar"
android:protectionLevel="dangerous" />
- <!-- Allows an application to write the user's calendar data. -->
+ <!-- Allows an application to write the user's calendar data.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CALENDAR"
android:permissionGroup="android.permission-group.CALENDAR"
android:label="@string/permlab_writeCalendar"
@@ -400,7 +395,9 @@
android:description="@string/permgroupdesc_sms"
android:priority="300" />
- <!-- Allows an application to send SMS messages. -->
+ <!-- Allows an application to send SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.SEND_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_sendSms"
@@ -408,28 +405,36 @@
android:permissionFlags="costsMoney"
android:protectionLevel="dangerous" />
- <!-- Allows an application to receive SMS messages. -->
+ <!-- Allows an application to receive SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveSms"
android:description="@string/permdesc_receiveSms"
android:protectionLevel="dangerous"/>
- <!-- Allows an application to read SMS messages. -->
+ <!-- Allows an application to read SMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_SMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_readSms"
android:description="@string/permdesc_readSms"
android:protectionLevel="dangerous" />
- <!-- Allows an application to receive WAP push messages. -->
+ <!-- Allows an application to receive WAP push messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_WAP_PUSH"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveWapPush"
android:description="@string/permdesc_receiveWapPush"
android:protectionLevel="dangerous" />
- <!-- Allows an application to monitor incoming MMS messages. -->
+ <!-- Allows an application to monitor incoming MMS messages.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECEIVE_MMS"
android:permissionGroup="android.permission-group.SMS"
android:label="@string/permlab_receiveMms"
@@ -446,6 +451,7 @@
additional emergency information (if Internet access is available)
when the alert is first received, and to delay presenting the info
to the user until after the initial alert dialog is dismissed.
+ <p>Protection level: dangerous
@hide Pending API council approval -->
<permission android:name="android.permission.READ_CELL_BROADCASTS"
android:permissionGroup="android.permission-group.SMS"
@@ -484,12 +490,14 @@
targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 4 or higher.-->
+ targetSdkVersion}</a> is 4 or higher.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_sdcardRead"
android:description="@string/permdesc_sdcardRead"
- android:protectionLevel="normal" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to write to external storage.
<p class="note"><strong>Note:</strong> If <em>both</em> your <a
@@ -503,49 +511,15 @@
<p>Starting in API level 19, this permission is <em>not</em> required to
read/write files in your application-specific directories returned by
{@link android.content.Context#getExternalFilesDir} and
- {@link android.content.Context#getExternalCacheDir}. -->
+ {@link android.content.Context#getExternalCacheDir}.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_sdcardWrite"
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 -->
<!-- ====================================================================== -->
@@ -558,14 +532,18 @@
android:description="@string/permgroupdesc_location"
android:priority="400" />
- <!-- Allows an app to access precise location. -->
+ <!-- Allows an app to access precise location.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:permissionGroup="android.permission-group.LOCATION"
android:label="@string/permlab_accessFineLocation"
android:description="@string/permdesc_accessFineLocation"
android:protectionLevel="dangerous" />
- <!-- Allows an app to access approximate location. -->
+ <!-- Allows an app to access approximate location.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:permissionGroup="android.permission-group.LOCATION"
android:label="@string/permlab_accessCoarseLocation"
@@ -592,7 +570,9 @@
targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 4 or higher. -->
+ targetSdkVersion}</a> is 4 or higher.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readPhoneState"
@@ -600,7 +580,9 @@
android:protectionLevel="dangerous" />
<!-- Allows an application to initiate a phone call without going through
- the Dialer user interface for the user to confirm the call. -->
+ the Dialer user interface for the user to confirm the call.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.CALL_PHONE"
android:permissionGroup="android.permission-group.PHONE"
android:permissionFlags="costsMoney"
@@ -617,7 +599,9 @@
targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 16 or higher.</p> -->
+ targetSdkVersion}</a> is 16 or higher.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.READ_CALL_LOG"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readCallLog"
@@ -634,21 +618,27 @@
targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
grants your app this permission. If you don't need this permission, be sure your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> is 16 or higher.</p> -->
+ targetSdkVersion}</a> is 16 or higher.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.WRITE_CALL_LOG"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_writeCallLog"
android:description="@string/permdesc_writeCallLog"
android:protectionLevel="dangerous" />
- <!-- Allows an application to add voicemails into the system. -->
+ <!-- Allows an application to add voicemails into the system.
+ <p>Protection level: dangerous
+ -->
<permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_addVoicemail"
android:description="@string/permdesc_addVoicemail"
android:protectionLevel="dangerous" />
- <!-- Allows an application to use SIP service. -->
+ <!-- Allows an application to use SIP service.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.USE_SIP"
android:permissionGroup="android.permission-group.PHONE"
android:description="@string/permdesc_use_sip"
@@ -657,7 +647,9 @@
<!-- Allows an application to see the number being dialed during an outgoing
call with the option to redirect the call to a different number or
- abort the call altogether. -->
+ abort the call altogether.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_processOutgoingCalls"
@@ -678,7 +670,9 @@
android:description="@string/permgroupdesc_microphone"
android:priority="600" />
- <!-- Allows an application to record audio. -->
+ <!-- Allows an application to record audio.
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.RECORD_AUDIO"
android:permissionGroup="android.permission-group.MICROPHONE"
android:label="@string/permlab_recordAudio"
@@ -704,7 +698,9 @@
<uses-feature>}</a> manifest element for <em>all</em> camera features.
If you do not require all camera features or can properly operate if a camera
is not available, then you must modify your manifest as appropriate in order to
- install on devices that don't support all camera features.</p> -->
+ install on devices that don't support all camera features.</p>
+ <p>Protection level: dangerous
+ -->
<permission android:name="android.permission.CAMERA"
android:permissionGroup="android.permission-group.CAMERA"
android:label="@string/permlab_camera"
@@ -725,14 +721,17 @@
android:priority="800" />
<!-- Allows an application to access data from sensors that the user uses to
- measure what is happening inside his/her body, such as heart rate. -->
+ measure what is happening inside his/her body, such as heart rate.
+ <p>Protection level: dangerous -->
<permission android:name="android.permission.BODY_SENSORS"
android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_bodySensors"
android:description="@string/permdesc_bodySensors"
android:protectionLevel="dangerous" />
- <!-- Allows an app to use fingerprint hardware. -->
+ <!-- Allows an app to use fingerprint hardware.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.USE_FINGERPRINT"
android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_useFingerprint"
@@ -740,7 +739,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 -->
<!-- ====================================================================== -->
<!-- ================================== -->
@@ -779,41 +812,13 @@
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 />
- <!-- Allows an application to broadcast an Intent to set an alarm for the user. -->
+ <!-- Allows an application to broadcast an Intent to set an alarm for the user.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.alarm.permission.SET_ALARM"
android:label="@string/permlab_setAlarm"
android:description="@string/permdesc_setAlarm"
@@ -824,11 +829,15 @@
<!-- =============================================================== -->
<eat-comment />
- <!-- Allows an application to modify and remove existing voicemails in the system -->
+ <!-- Allows an application to modify and remove existing voicemails in the system
+ <p>Protection level: system|signature
+ -->
<permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
android:protectionLevel="system|signature" />
- <!-- Allows an application to read voicemails in the system. -->
+ <!-- Allows an application to read voicemails in the system.
+ <p>Protection level: system|signature
+ -->
<permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
android:protectionLevel="system|signature" />
@@ -837,7 +846,9 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows an application to access extra location provider commands -->
+ <!-- Allows an application to access extra location provider commands
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"
android:label="@string/permlab_accessLocationExtraCommands"
android:description="@string/permdesc_accessLocationExtraCommands"
@@ -861,7 +872,10 @@
android:protectionLevel="signature|system" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
- <!-- Allows an application to create mock location providers for testing. -->
+ <!-- @SystemApi Allows an application to create mock location providers for testing.
+ <p>Protection level: signature
+ @hide
+ -->
<permission android:name="android.permission.ACCESS_MOCK_LOCATION"
android:protectionLevel="signature" />
@@ -870,25 +884,33 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows applications to open network sockets. -->
+ <!-- Allows applications to open network sockets.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.INTERNET"
android:description="@string/permdesc_createNetworkSockets"
android:label="@string/permlab_createNetworkSockets"
android:protectionLevel="normal" />
- <!-- Allows applications to access information about networks -->
+ <!-- Allows applications to access information about networks
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_NETWORK_STATE"
android:description="@string/permdesc_accessNetworkState"
android:label="@string/permlab_accessNetworkState"
android:protectionLevel="normal" />
- <!-- Allows applications to access information about Wi-Fi networks -->
+ <!-- Allows applications to access information about Wi-Fi networks.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_WIFI_STATE"
android:description="@string/permdesc_accessWifiState"
android:label="@string/permlab_accessWifiState"
android:protectionLevel="normal" />
- <!-- Allows applications to change Wi-Fi connectivity state -->
+ <!-- Allows applications to change Wi-Fi connectivity state.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_WIFI_STATE"
android:description="@string/permdesc_changeWifiState"
android:label="@string/permlab_changeWifiState"
@@ -935,13 +957,17 @@
<!-- ======================================= -->
<eat-comment />
- <!-- Allows applications to connect to paired bluetooth devices -->
+ <!-- Allows applications to connect to paired bluetooth devices.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BLUETOOTH"
android:description="@string/permdesc_bluetooth"
android:label="@string/permlab_bluetooth"
android:protectionLevel="normal" />
- <!-- Allows applications to discover and pair bluetooth devices -->
+ <!-- Allows applications to discover and pair bluetooth devices.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BLUETOOTH_ADMIN"
android:description="@string/permdesc_bluetoothAdmin"
android:label="@string/permlab_bluetoothAdmin"
@@ -965,7 +991,9 @@
<permission android:name="android.permission.BLUETOOTH_STACK"
android:protectionLevel="signature" />
- <!-- Allows applications to perform I/O operations over NFC -->
+ <!-- Allows applications to perform I/O operations over NFC.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.NFC"
android:description="@string/permdesc_nfc"
android:label="@string/permlab_nfc"
@@ -1005,7 +1033,9 @@
android:permissionGroupFlags="personalInfo"
android:priority="1000" />
- <!-- Allows access to the list of accounts in the Accounts Service -->
+ <!-- Allows access to the list of accounts in the Accounts Service.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.GET_ACCOUNTS"
android:permissionGroup="android.permission-group.CONTACTS"
android:protectionLevel="normal"
@@ -1023,32 +1053,42 @@
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to enter Wi-Fi Multicast mode -->
+ <!-- Allows applications to enter Wi-Fi Multicast mode.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
android:description="@string/permdesc_changeWifiMulticastState"
android:label="@string/permlab_changeWifiMulticastState"
android:protectionLevel="normal" />
- <!-- Allows access to the vibrator -->
+ <!-- Allows access to the vibrator.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.VIBRATE"
android:label="@string/permlab_vibrate"
android:description="@string/permdesc_vibrate"
android:protectionLevel="normal" />
- <!-- Allows access to the flashlight -->
+ <!-- Allows access to the flashlight.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.FLASHLIGHT"
android:label="@string/permlab_flashlight"
android:description="@string/permdesc_flashlight"
android:protectionLevel="normal" />
<!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
- from dimming -->
+ from dimming.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.WAKE_LOCK"
android:label="@string/permlab_wakeLock"
android:description="@string/permdesc_wakeLock"
android:protectionLevel="normal" />
- <!-- Allows using the device's IR transmitter, if available -->
+ <!-- Allows using the device's IR transmitter, if available.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.TRANSMIT_IR"
android:label="@string/permlab_transmitIr"
android:description="@string/permdesc_transmitIr"
@@ -1059,7 +1099,9 @@
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows an application to modify global audio settings -->
+ <!-- Allows an application to modify global audio settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
android:label="@string/permlab_modifyAudioSettings"
android:description="@string/permdesc_modifyAudioSettings"
@@ -1081,8 +1123,10 @@
<permission android:name="android.permission.ACCESS_MTP"
android:protectionLevel="signature|system" />
- <!-- Allows access to hardware peripherals. Intended only for hardware testing.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows access to hardware peripherals. Intended only for hardware testing.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.HARDWARE_TEST"
android:protectionLevel="signature" />
@@ -1191,7 +1235,9 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.InCallService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="system|signature" />
@@ -1205,7 +1251,9 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.ConnectionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
android:protectionLevel="system|signature" />
@@ -1230,7 +1278,9 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to manage access to documents, usually as part
- of a document picker. -->
+ of a document picker.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.MANAGE_DOCUMENTS"
android:protectionLevel="signature" />
@@ -1239,7 +1289,9 @@
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to disable the keyguard if it is not secure. -->
+ <!-- Allows applications to disable the keyguard if it is not secure.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.DISABLE_KEYGUARD"
android:description="@string/permdesc_disableKeyguard"
android:label="@string/permlab_disableKeyguard"
@@ -1306,7 +1358,9 @@
<permission android:name="android.permission.GET_DETAILED_TASKS"
android:protectionLevel="signature" />
- <!-- Allows an application to change the Z-order of tasks -->
+ <!-- Allows an application to change the Z-order of tasks.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.REORDER_TASKS"
android:label="@string/permlab_reorderTasks"
android:description="@string/permdesc_reorderTasks"
@@ -1334,12 +1388,19 @@
android:protectionLevel="normal" />
<!-- Allows an application to call
- {@link android.app.ActivityManager#killBackgroundProcesses}. -->
+ {@link android.app.ActivityManager#killBackgroundProcesses}.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
android:label="@string/permlab_killBackgroundProcesses"
android:description="@string/permdesc_killBackgroundProcesses"
android:protectionLevel="normal" />
+ <!-- @SystemApi @hide Allows an application to retrieve a package's importance.
+ This permission is not available to third party applications. -->
+ <permission android:name="android.permission.GET_PACKAGE_IMPORTANCE"
+ android:protectionLevel="signature|system" />
+
<!-- ================================== -->
<!-- Permissions affecting the display of other applications -->
<!-- ================================== -->
@@ -1353,20 +1414,24 @@
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="signature|system|appop" />
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
<!-- ================================== -->
<eat-comment />
- <!-- Allows applications to set the wallpaper -->
+ <!-- Allows applications to set the wallpaper.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_WALLPAPER"
android:label="@string/permlab_setWallpaper"
android:description="@string/permdesc_setWallpaper"
android:protectionLevel="normal" />
- <!-- Allows applications to set the wallpaper hints -->
+ <!-- Allows applications to set the wallpaper hints.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_WALLPAPER_HINTS"
android:label="@string/permlab_setWallpaperHints"
android:description="@string/permdesc_setWallpaperHints"
@@ -1382,7 +1447,9 @@
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signature|system" />
- <!-- Allows applications to set the system time zone -->
+ <!-- Allows applications to set the system time zone.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.SET_TIME_ZONE"
android:label="@string/permlab_setTimeZone"
android:description="@string/permdesc_setTimeZone"
@@ -1393,7 +1460,9 @@
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows an application to expand or collapse the status bar. -->
+ <!-- Allows an application to expand or collapse the status bar.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.EXPAND_STATUS_BAR"
android:label="@string/permlab_expandStatusBar"
android:description="@string/permdesc_expandStatusBar"
@@ -1404,36 +1473,46 @@
<!-- ============================================================== -->
<eat-comment />
- <!-- Allows an application to install a shortcut in Launcher -->
+ <!-- Allows an application to install a shortcut in Launcher.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
android:label="@string/permlab_install_shortcut"
android:description="@string/permdesc_install_shortcut"
- android:protectionLevel="dangerous"/>
+ android:protectionLevel="normal"/>
- <!-- Allows an application to uninstall a shortcut in Launcher -->
+ <!-- Allows an application to uninstall a shortcut in Launcher.
+ <p>Protection level: normal
+ -->
<permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:label="@string/permlab_uninstall_shortcut"
android:description="@string/permdesc_uninstall_shortcut"
- android:protectionLevel="dangerous"/>
+ android:protectionLevel="normal"/>
<!-- ==================================================== -->
<!-- Permissions related to accessing sync settings -->
<!-- ==================================================== -->
<eat-comment />
- <!-- Allows applications to read the sync settings -->
+ <!-- Allows applications to read the sync settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.READ_SYNC_SETTINGS"
android:description="@string/permdesc_readSyncSettings"
android:label="@string/permlab_readSyncSettings"
android:protectionLevel="normal" />
- <!-- Allows applications to write the sync settings -->
+ <!-- Allows applications to write the sync settings.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.WRITE_SYNC_SETTINGS"
android:description="@string/permdesc_writeSyncSettings"
android:label="@string/permlab_writeSyncSettings"
android:protectionLevel="normal" />
- <!-- Allows applications to read the sync stats -->
+ <!-- Allows applications to read the sync stats.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.READ_SYNC_STATS"
android:description="@string/permdesc_readSyncStats"
android:label="@string/permlab_readSyncStats"
@@ -1491,7 +1570,9 @@
android:description="@string/permdesc_persistentActivity"
android:protectionLevel="normal" />
- <!-- Allows an application to find out the space used by any package. -->
+ <!-- Allows an application to find out the space used by any package.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.GET_PACKAGE_SIZE"
android:label="@string/permlab_getPackageSize"
android:description="@string/permdesc_getPackageSize"
@@ -1513,7 +1594,9 @@
system to start and allowing applications to have themselves
running without the user being aware of them. As such, you must
explicitly declare your use of this facility to make that visible
- to the user. -->
+ to the user.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
android:label="@string/permlab_receiveBootCompleted"
android:description="@string/permdesc_receiveBootCompleted"
@@ -1522,7 +1605,9 @@
<!-- Allows an application to broadcast sticky intents. These are
broadcasts whose data is held by the system after being finished,
so that clients can quickly retrieve that data without having
- to wait for the next broadcast. -->
+ to wait for the next broadcast.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.BROADCAST_STICKY"
android:label="@string/permlab_broadcastSticky"
android:description="@string/permdesc_broadcastSticky"
@@ -1568,14 +1653,18 @@
<permission android:name="android.permission.WRITE_APN_SETTINGS"
android:protectionLevel="signature|system" />
- <!-- Allows applications to change network connectivity state -->
+ <!-- Allows applications to change network connectivity state.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.CHANGE_NETWORK_STATE"
android:description="@string/permdesc_changeNetworkState"
android:label="@string/permlab_changeNetworkState"
android:protectionLevel="normal" />
<!-- Allows an application to clear the caches of all installed
- applications on the device. -->
+ applications on the device.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.CLEAR_APP_CACHE"
android:protectionLevel="signatureOrSystem" />
@@ -1674,9 +1763,11 @@
<permission android:name="android.permission.STATUS_BAR_SERVICE"
android:protectionLevel="signature" />
- <!-- Allows an application to force a BACK operation on whatever is the
+ <!-- @SystemApi Allows an application to force a BACK operation on whatever is the
top activity.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.FORCE_BACK"
android:protectionLevel="signature" />
@@ -1694,15 +1785,19 @@
<permission android:name="android.permission.UPDATE_APP_OPS_STATS"
android:protectionLevel="signature|system" />
- <!-- Allows an application to open windows that are for use by parts
+ <!-- @SystemApi Allows an application to open windows that are for use by parts
of the system user interface.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
android:protectionLevel="signature" />
- <!-- Allows an application to manage (create, destroy,
+ <!-- @SystemApi Allows an application to manage (create, destroy,
Z-order) application tokens in the window manager.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.MANAGE_APP_TOKENS"
android:protectionLevel="signature" />
@@ -1711,10 +1806,12 @@
<permission android:name="android.permission.FREEZE_SCREEN"
android:protectionLevel="signature" />
- <!-- Allows an application to inject user events (keys, touch, trackball)
+ <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
into the event stream and deliver them to ANY window. Without this
permission, you can only deliver events to windows in your own process.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.INJECT_EVENTS"
android:protectionLevel="signature" />
@@ -1735,10 +1832,12 @@
<permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
android:protectionLevel="signature" />
- <!-- Allows an application to watch and control how activities are
+ <!-- @SystemApi Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:protectionLevel="signature" />
@@ -1756,9 +1855,11 @@
<permission android:name="android.permission.STOP_APP_SWITCHES"
android:protectionLevel="signature|system" />
- <!-- Allows an application to retrieve private information about
+ <!-- @SystemApi Allows an application to retrieve private information about
the current top activity, such as any assist context it can provide.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
android:protectionLevel="signature" />
@@ -1770,28 +1871,38 @@
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.inputmethodservice.InputMethodService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_INPUT_METHOD"
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.media.midi.MidiDeviceService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.printservice.PrintService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_PRINT_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
- the system can bind to it. -->
+ the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_NFC_SERVICE"
android:protectionLevel="signature" />
@@ -1801,22 +1912,30 @@
android:protectionLevel="signature" />
<!-- Must be required by a TextService (e.g. SpellCheckerService)
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_TEXT_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.net.VpnService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_VPN_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_WALLPAPER"
android:protectionLevel="signature|system" />
<!-- Must be required by a {@link android.service.voice.VoiceInteractionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_VOICE_INTERACTION"
android:protectionLevel="signature" />
@@ -1833,7 +1952,9 @@
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.media.tv.TvInputService}
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_TV_INPUT"
android:protectionLevel="signature|system" />
@@ -1850,7 +1971,9 @@
android:protectionLevel="signature" />
<!-- Must be required by device administration receiver, to ensure that only the
- system can interact with it. -->
+ system can interact with it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_DEVICE_ADMIN"
android:protectionLevel="signature" />
@@ -1860,14 +1983,18 @@
<permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
android:protectionLevel="signature|system" />
- <!-- Allows low-level access to setting the orientation (actually
+ <!-- @SystemApi Allows low-level access to setting the orientation (actually
rotation) of the screen.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_ORIENTATION"
android:protectionLevel="signature" />
- <!-- Allows low-level access to setting the pointer speed.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows low-level access to setting the pointer speed.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.SET_POINTER_SPEED"
android:protectionLevel="signature" />
@@ -1885,7 +2012,9 @@
<!-- Allows an application to request installing packages. Apps
targeting APIs greater than 22 must hold this permission in
- order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.-->
+ order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
android:label="@string/permlab_requestInstallPackages"
android:description="@string/permdesc_requestInstallPackages"
@@ -1896,8 +2025,10 @@
<permission android:name="android.permission.INSTALL_PACKAGES"
android:protectionLevel="signature|system" />
- <!-- Allows an application to clear user data.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows an application to clear user data.
+ <p>Not for use by third-party applications
+ @hide
+ -->
<permission android:name="android.permission.CLEAR_APP_USER_DATA"
android:protectionLevel="signature" />
@@ -1930,8 +2061,10 @@
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
android:protectionLevel="signatureOrSystem" />
- <!-- Allows an application to use SurfaceFlinger's low level features.
- <p>Not for use by third-party applications. -->
+ <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
android:protectionLevel="signature" />
@@ -1997,8 +2130,10 @@
<permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
android:protectionLevel="signature|system" />
- <!-- Required to be able to disable the device (very dangerous!).
- <p>Not for use by third-party applications.. -->
+ <!-- @SystemApi Required to be able to disable the device (very dangerous!).
+ <p>Not for use by third-party applications.
+ @hide
+ -->
<permission android:name="android.permission.BRICK"
android:protectionLevel="signature" />
@@ -2007,9 +2142,11 @@
<permission android:name="android.permission.REBOOT"
android:protectionLevel="signature|system" />
- <!-- Allows low-level access to power management.
- <p>Not for use by third-party applications. -->
- <permission android:name="android.permission.DEVICE_POWER"
+ <!-- @SystemApi Allows low-level access to power management.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="android.permission.DEVICE_POWER"
android:protectionLevel="signature" />
<!-- Allows access to the PowerManager.userActivity function.
@@ -2023,23 +2160,27 @@
<!-- Run as a manufacturer test application, running as the root user.
Only available when the device is running in manufacturer test mode.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.FACTORY_TEST"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast a notification that an application
package has been removed.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast an SMS receipt notification.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_SMS"
android:protectionLevel="signature" />
<!-- Allows an application to broadcast a WAP PUSH receipt notification.
- <p>Not for use by third-party applications. -->
+ <p>Not for use by third-party applications.
+ -->
<permission android:name="android.permission.BROADCAST_WAP_PUSH"
android:protectionLevel="signature" />
@@ -2084,7 +2225,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.
@@ -2282,7 +2423,9 @@
<permission android:name="android.permission.ACCESS_NOTIFICATIONS"
android:protectionLevel="signature|system" />
- <!-- Marker permission for applications that wish to access notification policy. -->
+ <!-- Marker permission for applications that wish to access notification policy.
+ <p>Protection level: normal
+ -->
<permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"
android:description="@string/permdesc_access_notification_policy"
android:label="@string/permlab_access_notification_policy"
@@ -2326,13 +2469,17 @@
<!-- Must be required by an {@link
android.service.notification.NotificationListenerService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a {@link
android.service.chooser.ChooserTargetService}, to ensure that
- only the system can bind to it. -->
+ only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
android:protectionLevel="signature" />
@@ -2344,7 +2491,9 @@
android:protectionLevel="signature" />
<!-- Must be required by an {@link android.service.dreams.DreamService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.BIND_DREAM_SERVICE"
android:protectionLevel="signature" />
@@ -2399,7 +2548,9 @@
<!-- The system process that is allowed to bind to services in carrier apps will
have this permission. Carrier apps should use this permission to protect
- their services that only the system is allowed to bind to. -->
+ their services that only the system is allowed to bind to.
+ <p>Protection level: system|signature
+ -->
<permission android:name="android.permission.BIND_CARRIER_SERVICES"
android:label="@string/permlab_bindCarrierServices"
android:description="@string/permdesc_bindCarrierServices"
@@ -2421,6 +2572,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"/>
@@ -2433,8 +2591,7 @@
android:backupAgent="com.android.server.backup.SystemBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_android"
- android:supportsRtl="true"
- android:theme="@style/Theme.Material.DayNight.DarkActionBar">
+ android:supportsRtl="true">
<activity android:name="com.android.internal.app.ChooserActivity"
android:theme="@style/Theme.DeviceDefault.Resolver"
android:finishOnCloseSystemDialogs="true"
@@ -2445,6 +2602,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"
@@ -2467,7 +2625,7 @@
android:label="@string/managed_profile_label">
</activity-alias>
<activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
- android:theme="@style/Theme.Material.DayNight.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/heavy_weight_switcher_title"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
@@ -2500,7 +2658,7 @@
<activity android:name="android.accounts.ChooseAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@style/Theme.Material.DayNight.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2508,14 +2666,14 @@
<activity android:name="android.accounts.ChooseTypeAndAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@style/Theme.Material.DayNight.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
<activity android:name="android.accounts.ChooseAccountTypeActivity"
android:excludeFromRecents="true"
- android:theme="@style/Theme.Material.DayNight.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
@@ -2523,19 +2681,19 @@
<activity android:name="android.accounts.CantAddAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@style/Theme.Material.DayNight.Dialog.NoActionBar"
+ android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
android:process=":ui">
</activity>
<activity android:name="android.accounts.GrantCredentialsPermissionActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@style/Theme.Material.DayNight.DialogWhenLarge"
+ android:theme="@style/Theme.Material.Light.DialogWhenLarge"
android:process=":ui">
</activity>
<activity android:name="android.content.SyncActivityTooManyDeletes"
- android:theme="@style/Theme.Material.DayNight.Dialog"
+ android:theme="@style/Theme.Material.Light.Dialog"
android:label="@string/sync_too_many_deletes"
android:process=":ui">
</activity>
@@ -2555,7 +2713,7 @@
</activity>
<activity android:name="com.android.internal.app.NetInitiatedActivity"
- android:theme="@style/Theme.Material.DayNight.Dialog.Alert"
+ android:theme="@style/Theme.Material.Light.Dialog.Alert"
android:excludeFromRecents="true"
android:process=":ui">
</activity>
diff --git a/core/res/res/drawable-hdpi/perm_group_storage.png b/core/res/res/drawable-hdpi/perm_group_storage.png
deleted file mode 100644
index 598e1cc..0000000
--- a/core/res/res/drawable-hdpi/perm_group_storage.png
+++ /dev/null
Binary files differ
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_storage.png b/core/res/res/drawable-mdpi/perm_group_storage.png
deleted file mode 100644
index b7a06fb..0000000
--- a/core/res/res/drawable-mdpi/perm_group_storage.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 2fc40564..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_storage.png b/core/res/res/drawable-xhdpi/perm_group_storage.png
deleted file mode 100644
index a2d4d5e..0000000
--- a/core/res/res/drawable-xhdpi/perm_group_storage.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_storage.png b/core/res/res/drawable-xxhdpi/perm_group_storage.png
deleted file mode 100644
index 837211e..0000000
--- a/core/res/res/drawable-xxhdpi/perm_group_storage.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_storage.png b/core/res/res/drawable-xxxhdpi/perm_group_storage.png
deleted file mode 100644
index 918b3ed..0000000
--- a/core/res/res/drawable-xxxhdpi/perm_group_storage.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/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 11078d3..62131da 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -14,11 +14,14 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:pathData="M20,8H8c-2.2,0 -4,1.8 -4,4l0,24c0,2.2 1.8,4 4,4h32c2.2,0 4,-1.8 4,-4V16c0,-2.2 -1.8,-4 -4,-4H24L20,8z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M0,0h48v48H0z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M27,9c2.2,0 4,-1.8 4,-4s-1.8,-4 -4,-4 -4,1.8 -4,4 1.8,4 4,4zm-7.2,27.8l1.9,-8.8 4.3,4v12h4V28.9l-4.1,-4.1 1.2,-6C29.7,22 33.6,24 38,24v-4c-3.7,0 -6.9,-2 -8.7,-4.9l-1.9,-3.2c-0.7,-1.2 -2,-1.9 -3.4,-1.9 -0.5,0 -1,0.1 -1.5,0.3L12,14.6V24h4v-6.7l3.5,-1.4L16.4,32l-9.8,-1.9 -0.8,3.9s14,2.7 14,2.8z"/>
</vector>
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/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
index e863b28..04647b1 100644
--- a/core/res/res/layout/date_picker_view_animator_material.xml
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -32,6 +32,7 @@
<android.widget.YearPickerView
android:id="@+id/date_picker_year_picker"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:scrollIndicators="bottom" />
</com.android.internal.widget.DialogViewAnimator>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 1b58ce5..482f91f 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -18,7 +18,8 @@
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:minWidth="@dimen/floating_toolbar_menu_button_side_padding"
+ android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width"
+ android:minHeight="@dimen/floating_toolbar_height"
android:paddingStart="@dimen/floating_toolbar_menu_button_side_padding"
android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding"
android:paddingTop="0dp"
diff --git a/core/res/res/layout/year_label_text_view.xml b/core/res/res/layout/year_label_text_view.xml
index 6240c4b..3ea719d 100644
--- a/core/res/res/layout/year_label_text_view.xml
+++ b/core/res/res/layout/year_label_text_view.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/month_text_view"
+ android:id="@id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/listPreferredItemHeightSmall"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 03cee7d..d3e1275 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ligging"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"verkry toegang tot hierdie toestel se ligging"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Jou sosiale inligting"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte toegang tot inligting oor jou kontakte en sosiale verbindings."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"gaan by jou kalender in"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"stuur en bekyk SMS-boodskappe"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stoor"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"verkry toegang tot foto\'s, media en lêers op jou toestel"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Gebruikerwoordeboek"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lees of skryf woorde in gebruikerswoordeboek."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Boekmerke en geskiedenis"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte toegang tot boekmerke en blaaiergeskiedenis."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"neem oudio op"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"neem foto\'s en neem video op"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Foon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"maak en bestuur foonoproepe"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"toeganginligting oor jou lewenstekens en fisieke aktiwiteit"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Liggaamsensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"kry toegang tot sensordata oor jou lewenstekens"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Haal venster-inhoud op"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ondersoek die inhoud van \'n venster waarmee jy interaksie het."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Skakel Verken deur raak aan"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Laat die program toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Laat die program toe om jou TV se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lees jou eie kontakkaart"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Laat die program toe om persoonlike profielinligting wat op jou toestel gestoor is, soos jou naam en kontakbesonderhede, te lees. Dit beteken dat die program jou kan identifiseer en jou profielinligting moontlik aan ander mense kan stuur."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"verander jou eie kontakkaart"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Laat die program toe om persoonlike profielinligting, soos jou naam en kontakinligting, wat op jou toestel gestoor is, te verander of daarby te voeg. Dit beteken dat die program jou kan identifiseer en moontlik jou profielinligting na ander mense kan stuur."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"liggaamsensors (soos hartklopmonitors)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Laat die program toe om toegang te verkry tot data van sensors af wat jou fisieke toestand, soos jou polsslag, monitor."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lees jou sosiale stroom"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Laat die program toe om toegang tot sosiale opdaterings van jou en jou vriende te verkry en dit te sinkroniseer. Wees versigtig wanneer jy inligting deel -- dit laat die program toe om kommunikasie tussen jou en jou vriende op sosiale netwerke te lees, ongeag vertroulikheid. Let wel: hierdie toestemming mag dalk nie op alle sosiale netwerke afgedwing word nie."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skryf aan jou sosiale stroom"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Laat die program toe om sosiale opdaterings van vriende te vertoon. Wees versigtig wanneer jy inligting deel -- dit laat die program toe om boodskappe te vervaardig wat lyk of dit van \'n vriend af kom. Let wel: hierdie toestemming mag dalk nie op alle sosiale netwerke afgedwing word nie."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lees kalenderafsprake plus vertroulike inligting"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Laat die program toe om alle kalendergebeure wat op jou tablet gestoor is, insluitend dié van vriende en medewerkers, te lees. Dit kan moontlik die program toelaat om jou kalenderdata te deel of te stoor, ongeag van vertroulikheid of sensitiwiteit."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Laat die program toe om alle kalendergeleenthede te lees wat op jou TV geberg is, insluitend die van vriende of kollegas. Dit kan die program toelaat om jou kalenderdata te deel of te stoor, ongeag vertroulikheid of sensitiwiteit."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Laat \'n program toe om die sinkroniseringinstellings van \'n rekening te verander. Byvoorbeeld, dit kan gebruik word om sinkronisasie van die People-program met \'n ander rekening te aktiveer."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lees sinkroniseerstatistiek"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Laat \'n program toe om die sinkroniseringstatistieke van \'n rekening te lees, insluitend die geskiedenis van sinkroniseringgebeure en hoeveel data gesinkroniseer is."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lees terme wat jy by die woordeboek gevoeg het"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Laat ’n program toe om alle woorde, name en frases wat die gebruiker moontlik in die gebruikerwoordeboek gestoor het, te lees."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"voeg woorde by gebruiker-gedefinieerde woordeboek"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Laat die program toe om nuwe woorde in die gebruikerwoordeboek te skryf."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lees jou USB-berging se inhoud"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lees jou SD-kaart se inhoud"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Laat die program toe om die USB-geheue se inhoud te lees."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a676a3d..3ab18fa 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"መገኛ አካባቢ"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"የዚህን መሣሪያ አካባቢ ይድረሱበት"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ማህበራዊ መረጃዎ"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ወደ የእውቂያዎችህና የማህበራዊ ግንኙነቶችህ መረጃ ቀጥተኛ መዳረሻ።"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ቀን መቁጠሪያ"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"ኤስኤምኤስ"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"የኤስኤምኤስ መልዕክቶችን ይላኩና ይመልከቱ"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ማከማቻ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"በመሳሪያዎ ላይ ያሉ ፎቶዎችን፣ ማህደረመረጃን እና ፋይሎችን ይድረሱ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"የተጠቃሚ መዝገበ ቃላት"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"በተጠቃሚ መዝገበቃላት ላይ ቃሎችን አንብብ ወይም ጻፍ።"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ዕልባቶች እና ታሪክ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ወደ ዕልባቶችና የአሳሽ ታሪክ ቀጥተኛ መዳረሻ።"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ማይክሮፎን"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ኦዲዮ ይቅዱ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ካሜራ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ስዕሎች ያንሱ እና ቪዲዮ ይቅረጹ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ስልክ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"የስልክ ጥሪዎች ያድርጉ እና ያስተዳድሩ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"አነፍናፊዎች"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ስለእርስዎ አስፈላጊ ምልክቶች እና አካላዊ እንቅስቃሴ መረጃ ይድረሱ"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ስለአስፈላጊ ምልክቶችዎ ያሉ የዳሳሽ ውሂብ ይድረሱ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"የመስኮት ይዘት ሰርስረው ያውጡ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"መስተጋበር የሚፈጥሩት የመስኮት ይዘት ይመርምሩ።"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"በመንካት ያስሱን ያብሩ"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"መተግበሪያው ስለገቢ እና ወጪ ጥሪዎች ያለ ውሂብም ጨምሮ የቴሌቪዥንዎ ምዝግብ ማስታወሻ እንዲይቀርይ ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ይህን ተጠቅመው የስልክዎን ምዝግብ ማስታወሻ ሊደመስሱ ወይም ሊቀይሩ ይችላሉ።"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"የራስዎን የዕውቂያ ካርድ ያንብቡ"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"መተግበሪያው ልክ እንደ ስምዎ እና የእውቂያ መረጃዎ ያሉ በመሳሪያዎ ላይ የተከማቹ የግል መገለጫ መረጃዎችን እንዲያነብ ይፈቅድለታል። ይህም ማለት መተግበሪያው ለይቶ ሊያውቁዎ እና የመገለጫ መረጃዎን ለሌሎች ሊልክ ይችላል።"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"የራስዎን የዕውቂያ ካርድ ያስተካክሉ"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"መተግበሪያው ልክ እንደ ስምዎ እና የእውቂያ መረጃዎ ያሉ በመሳሪያዎ ላይ የተከማቹ የግል መገለጫ መረጃዎችን እንዲቀይር ወይም እንዲያክልባቸው ይፈቅድለታል። ይህም ማለት መተግበሪያው ለይቶ ሊያውቅዎ እና የመገለጫ መረጃዎን ለሌሎች ሊልክ ይችላል።"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"የሰውነት መመርመሪያዎች (እንደ የልብ ምት መቆጣጠሪያዎች)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"እንደ የእርስዎ የልብ ምት የመሳሰሉ ያሉበትን አካላዊ ሁኔታ ከሚቆጣጠሩ ሰውነት ዳሳሾች ውሂብ ላይ እንዲደርስ ለመተግበሪያው ይፈቅደለታል።"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"የእርስዎን ማህበራዊ የውይይት ክፍሎች ያንብቡ"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"መተግበሪያው የአንተንና የጓኞችህን ማህበራዊ ዝማኔዎችን እንዲደርስባቸው እና እንዲያመሳስላቸው ይፈቅድለታል። መረጃ ስታጋራ ተጠንቀቅ -- ይህ መተግበሪያው ሚስጥራዊነትን ከግምት ሳያስገባ በማህበራዊ አውታረ መረቦች በአንተ እና በጓደኞችህ መካከል የሚደረጉ ግንኙነቶችን እንዲያነብ ይፈቅድለታል። ማስታወሻ፦ ይህ ፈቃድ ለሁሉም ማህበራዊ አውታር መረቦች ላይ ላይፈጸም ይችላል።"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ወደ የእርስዎ ማህበራዊ የውይይት ክፍሎች ይጻፉ"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"መተግበሪያው ከጓኞችህን ማህበራዊ ዝማኔዎችን እንዲያሳይ ይፈቅድለታል። መረጃ ስታጋራ ተጠንቀቅ -- ይህ መተግበሪያው ከጓደኛ የመጡ የሚመስሉ መልዕክቶችን እንዲያዘጋጅ ይፈቅድለታል። ማስታወሻ፦ ይህ ፈቃድ በሁሉም ማህበራዊ አውታረ መረቦች ላይ ላይፈጸም ይችላል።"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"የቀን መቁጠሪያ ክስተቶች ተጨማሪ ሚስጥራዊ መረጃ አንብብ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"መተግበሪያው የጓደኞችን ወይም የስራ ባልደረቦችን ጨምሮ ሁሉንም በጡባዊ ቱኮህ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶች እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው የቀን መቁጠሪያ ውሂብህን ሚስጥራዊቱን ከግምት ሳያስገባ እንዲያጋራ ወይም እንዲያስቀምጥ ሊፈቅድለት ይችላል።"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"መተግበሪያው የጓደኛዎች ወይም የስራ ባልደረባዎችም ጨምሮ በእርስዎ ቴሌቪዥን ላይ የተከማቹ ሁሉንም የቀን መቁጠሪያ ክስተቶች እንዲያነብ ያስችለዋል። ይሄ ሚስጥራዊነት ወይም ጥንቃቄ ፈላጊነት ከግምት ውስጥ ሳይገባ መተግበሪያው የቀን መቁጠሪያዎ ውሂብ እንዲያጋራ ወይም እንዲያስቀምጥ ሊፈቅድለት ይችላል።"</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"መተግበሪያው የመለያ ማመሳሰል ቅንብሮችን እንዲያስተካክል ይፈቅድለታል። ለምሳሌ ይህ የሰዎች መተግበሪያን ከመለያ መመሳሰልን ለማንቃት ጥቅም ላይ ሊውል ይችላል።"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"የሥምሪያ ስታስቲክስ አንብብ"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"መተግበሪያው የማመሳሰል ክስተቶችን ታሪክ እና የተመሳሰለውን የውሂብ መጠን ጨምሮ የመለያን የማመሳሰል ስታትስቲክስ እንዲያነብ ይፈቅድለታል።"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"መዝገበ ቃላቱ ላይ ያከልካቸውን ቃላት አንብብ"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"መተግበሪያው ተጠቃሚው በተጠቃሚው መዝገበ-ቃላት አከማችቷቸው ሊሆኑ የሚችሉ ሁሉንም ቃላት፣ ስሞችና ሐረጋት እንዲያነባቸው ይፈቅድለታል።"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"በተጠቃሚ በተገለጸ መዝገበ ቃላት ላይ ቃላትን ያክላል"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"በተጠቃሚ መዝገበ ቃላት ውስጥ አዲስ ቃል እንዲጽፍ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"የUSB ማከማቻዎን ይዘቶች ያንብቡ"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"የSD ካርድህን ይዘቶች አንብብ"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"መተግበሪያው የእርስዎ USB ማከማቻ ይዘቶችን እንዲያነብ ያስችለዋል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4d5e798..23f802b 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,32 +228,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"الموقع"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"الوصول إلى موقع هذا الجهاز"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"المعلومات الاجتماعية"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"الدخول المباشر إلى معلومات عن جهات الاتصال والاتصالات الاجتماعية."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"التقويم"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"الوصول تقويمك"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"إرسال رسائل قصيرة SMS وعرضها"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"التخزين"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"الوصول إلى الصور والوسائط والملفات على جهازك"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"قاموس المستخدم"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"قراءة الكلمات وكتابتها في قاموس المستخدم."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"الإشارات المرجعية والسجل"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"الدخول المباشر إلى الإشارات المرجعية وسجل المتصفح."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"الميكروفون"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"تسجيل الصوت"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"الكاميرا"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"التقاط صور وتسجيل فيديو"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"الهاتف"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"إجراء مكالمات هاتفية وإدارتها"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"أجهزة الاستشعار"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"الوصول إلى المعلومات عن علاماتك الحيوية ونشاطك البدني"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"أجهزة استشعار الجسم"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"الوصول إلى بيانات المستشعر حول علاماتك الحيوية"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"استرداد محتوى النافذة"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"فحص محتوى نافذة يتم التفاعل معها."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"تشغيل الاستكشاف باللمس"</string>
@@ -337,16 +330,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"للسماح للتطبيق بتعديل سجل مكالمات الجهاز اللوحي، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمسح سجل المكالمات أو تعديله."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"يتيح للتطبيق تعديل سجل مكالمات التلفزيون، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمسح سجل المكالمات أو تعديله."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"للسماح للتطبيق بتعديل سجل مكالمات الهاتف، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمحو سجل المكالمات أو تعديله."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"قراءة بطاقة الاتصال الخاصة"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"للسماح للتطبيق بقراءة المعلومات الشخصية في الملف الشخصي المخزنة على الجهاز، مثل اسمك ومعلومات جهات الاتصال. ويعني ذلك أنه يمكن للتطبيق التعرف عليك كما يمكنه إرسال معلومات ملفك الشخصي إلى الآخرين."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"تعديل بطاقة جهة الاتصال الخاصة"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"للسماح للتطبيق بتغيير المعلومات الشخصية في الملف الشخصي المخزنة على الجهاز أو الإضافة إليها، مثل اسمك ومعلومات جهات الاتصال. ويعني ذلك أنه يمكن للتطبيق التعرف عليك كما يمكنه إرسال معلومات ملفك الشخصي إلى الآخرين."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"أجهزة استشعار الجسم (مثل شاشات معدل ضربات القلب)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"للسماح للتطبيق بالدخول إلى البيانات من المستشعرات التي تراقب الحالة البدنية، مثل معدل نبضات القلب."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"قراءة المشاركات الاجتماعية"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"للسماح للتطبيق بالدخول إلى التحديثات الاجتماعية منك ومن أصدقائك ومزامنتها. توخ الحذر عند مشاركة المعلومات، حيث يتيح هذا للتطبيق قراءة عمليات التواصل بينك وبين أصدقائك على الشبكات الاجتماعية، بغض النظر عن مدى السرية. ملاحظة: لا يجوز فرض هذا الإذن على جميع الشبكات الاجتماعية."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"كتابة إلى المشاركات الاجتماعية"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"للسماح للتطبيق بعرض التحديثات الاجتماعية منك ومن أصدقائك. توخ الحذر عند مشاركة المعلومات، حيث يتيح هذا للتطبيق إنشاء رسائل يبدو أنها واردة من صديق. ملاحظة: لا يجوز فرض هذا الإذن على جميع الشبكات الاجتماعية."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"قراءة أحداث التقويم بالإضافة إلى المعلومات السرية"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"للسماح للتطبيق بقراءة جميع أحداث التقويم المخزنة على الجهاز اللوحي، بما في ذلك أحداث التقويم التابعة للأصدقاء أو زملاء العمل. وقد يتيح هذا للتطبيق مشاركة بيانات التقويم أو حفظها، بغض النظر عن مدى سرية البيانات أو حساسيتها."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"يتيح للتطبيق قراءة جميع أحداث التقويم المخزنة على التلفزيون، بما في ذلك أحداث الأصدقاء أو زملاء العمل. وقد يتيح هذا للتطبيق مشاركة بيانات التقويم أو حفظها، بغض النظر عن مدى السرية أو الحساسية."</string>
@@ -459,10 +444,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"للسماح للتطبيق بتعديل إعدادات المزامنة لحساب ما. على سبيل المثال، يمكن استخدام ذلك لتمكين مزامنة تطبيق \"الأشخاص\" مع حساب ما."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"قراءة إحصاءات المزامنة"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"للسماح للتطبيق بقراءة إحصائيات المزامنة لحساب ما، بما في ذلك سجل الأحداث المتزامنة ومقدار البيانات التي تمت مزامنتها."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"قراءة المصطلحات التي أضفتها إلى القاموس"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"للسماح للتطبيق بقراءة جميع الكلمات والأسماء والعبارات التي ربما يكون المستخدم قد خزنها في قاموس المستخدم."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"إضافة كلمات إلى القاموس المعرّف بواسطة المستخدم"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"للسماح للتطبيق بكتابة كلمات جديدة في قاموس المستخدم."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"قراءة محتويات وحدة تخزين USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"قراءة محتويات بطاقة SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"للسماح للتطبيق بقراءة محتويات وحدة تخزين USB."</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 3f2e6af..2871b9c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Yer"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"bu cihazın məkanını əldə edin"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosial məlumatınız"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktlarınız və sosial əlaqələriniz haqqında məlumata birbaşa giriş."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"təqvimə daxil olun"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"göndərin və SMS mesajlarına baxın"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Yaddaş"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"cihazınızda foto, media və fayllara daxil olun"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"İstifadəçi Sözlüyü"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"İstifadəçi lüğətində sözləri oxuyun və ya yazın."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Əlfəcinlər və Tarixçə"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Əlfəcinlərə və brauzer tarixinə birbaşa icazə."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"səsi qeydə alın"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"şəkil çəkin və video yazın"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon zəngləri edin və onları idarə edin"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorlar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"həyati əlamətlər və fiziki aktivliyiniz haqqında məlumatlara daxil olun"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Bədən Sensorları"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Həyati əlamətlər haqqında sensor dataya daxil olun"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pəncərənin məzmununu əldə edin"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tətbiqə planşetinizdəki zəng jurnalını, həmçinin gedən və gələn zənglərin siyahısını dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, zəng jurnalınıza dəyişiklik edə bilər."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Proqrama TV-nizin zəng jurnalını, o cümlədən daxil olan və çıxan zənglərlə bağlı məlumatları dəyişdirmək imkanı verə bilər. Zərərli proqramlar zəng jurnalınızı silmək və ya dəyişdirmək üçün bundan istifadə edə bilər."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tətbiqə sizin daxil olan və gedən zənglər daxil olmaqla telefon zəngi loqlarınızı redaktə etmək icazəsi verir. Zərərli tətbiqlər bundan telefon loqlarınızı silmək və ya redaktə etmək üçün istifadə edə bilər."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"öz kontakt kartınızı oxuyun"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını oxuma icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"sizin kontakt kartınızda dəyişiklik etmək"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını dəyişmək və ya əlavə etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"bədən sensorları (ürək döyüntüsü sayı kimi)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Tətbiqə ürək döyüntüsü kimi fiziki durumunuzu izləməyən sensorların datasına daxil olmağa icazə verir."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosial lentinizi oxuyur"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tətbiqə Sizin və dostlarınızın sosial güncəllərini əldə etmək və sinxronizə etmək icazəsi verir. Məlumat paylaşarkən diqqətli olun - konfidensiallıqdan asılı olmayaraq bu, Siz və dostlarınız arasında sosial şəbəkələrdəki danışığı oxumaq imkanı verir. Qeyd: bu icazə bütün sosial şəbəkələrdə icra edilə bilməz."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosial axınınıza yazır"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tətbiqə dostlarınızdan sosial yenilənmələri göstərmə icazəsi verir. Məlumat paylaşarkən diqqətli olun - bu dostlarınızdan gələn mesajı emal etməyə izn verir. Qeyd: bu icazə bütün sosial şəbəkələrə şamil olunmaya bilər."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"təqvim tədbirlərini və konfidensial məlumatları oxuyur"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tətbiqə dostlarınızın və əməkdaşlarınızın planşetinizdə yerləşən kalendar tədbirlərini oxumağa icazə verir. Bu tətbiqə konfidensiallıq və ya həssaslıqdan asılı olmayaraq sizin kalendar məlumatlarınızı paylaşmaq və ya saxlamağa imkan yaradır."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Proqrama TV-də saxlanan, o cümlədən dostlar və həmkarların bütün təqvim hadisələrini oxumaq imkanı verir. Bu, proqrama məxfilik və ya həssaslıqdan asılı olmayaraq təqvim məlumatlarınızı paylaşmaq və ya saxlamaq icazəsi verə bilər."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Tətbiqə hesab üçün sinxronizasiya nizamlarını dəyişməyə icazə verir. Məsələn, bu istifadəçi hesablı Şəxslər tətbiqinin sinxronizasiyasını başlamaq üçün istifadə edilə bilər."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"sinxronizasiya statistikasını oxumaq"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Tətbiqə sync tədbirlərinin tarixçəsi və nə qədər datanın sinx olduğu da daxil olmaqla bərabər, hər hansı bir hesab üçün olan sinx statlarını oxumağa imkan verir."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lüğətə əlavə etdiyiniz şərtləri oxumaq"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Tətbiqə istifadəçinin lüğətdə saxladığı bütün sözləri, adları və frazaları oxumaq icazəsi verir."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"istifadəçi lüğətinə sözlər əlavə etmək"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tətbiqə istifadəçi lüğətinə yeni sözlər yazmağa imkan verir."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB yaddaşınızın kontentini oxuyun"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD kartınızın kontentini oxuyun"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Tətbiqə USB yaddaşdan kontent oxuma icazəsi verir."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 21969d0..0f39944 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"достъп до местоположението на това устройство"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Социалната ви информация"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Осъществяване на директен достъп до информация за контактите и социалните ви връзки."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"достъп до календара ви"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"изпращане и преглед на SMS съобщения"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Съхранение"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"достъп до снимките, мултимедията и файловете на устройството ви"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Потребителски речник"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Четене или запис на думи в потребителския речник."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Отметки и история"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Осъществяване на директен достъп до отметките и историята на браузъра."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"запис на звук"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"правене на снимки и запис на видеоклипове"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"извършване и управление на телефонни обаждания"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"достъп до информацията за вашите жизнени показатели и физическа активност"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"достъп до сензорните данни за жизнените ви показатели"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Извличане на съдържанието от прозореца"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Инспектиране на съдържанието на прозорец, с който взаимодействате."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включване на изследването чрез докосване"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Разрешава на приложението да променя списъка с обаждания на таблета ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Разрешава на приложението да променя списъка с обажданията на телевизора ви, включително данните за входящите и изходящите повиквания. Злонамерените приложения може да използват това, за да изтрият или променят списъка с обажданията ви."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Разрешава на приложението да променя списъка с обаждания на телефона ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"четене на собств. ви карт. с данни за контакт"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Разрешава на приложението да чете информацията от личния потребителски профил, съхранена на устройството ви, например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща информацията за потребителския ви профил на други хора."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"промяна на собств. ви карт. с данни за контакт"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Разрешава на приложението да променя или добавя към личния потребителски профил информация, съхранена на устройството ви, като например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща данните за потребителския ви профил на други хора."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (като монитори за сърдечния ритъм)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Разрешава на приложението да осъществява достъп до данните от сензорите, които следят физическото ви състояние, като например сърдечния ви ритъм."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"четене на социалния ви поток"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Разрешава на приложението да осъществява достъп и да синхронизира социални актуализации от вас и приятелите ви. Бъдете внимателни при споделянето на информация – това позволява на приложението да чете съобщения помежду ви в социалните мрежи независимо от поверителността. Забележка: Възможно е ограниченията на това разрешение да не могат да бъдат наложени във всички социални мрежи."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писане в социалния ви поток"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Разрешава на приложението да показва социални актуализации от приятелите ви. Бъдете внимателни при споделянето на информация – това позволява на приложението да генерира съобщения, които изглежда, че идват от приятел. Забележка: Възможно е ограниченията на разрешението да не могат да бъдат наложени във всички социални мрежи."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"четене на събития от календари плюс поверителна информация"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Разрешава на приложението да чете всички събития от календари, съхранени на таблета ви, включително тези на приятели или колеги. Това може да му позволи да споделя или запазва данните от календара ви независимо от поверителността."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Разрешава на приложението да чете всички съхранявани в телевизора ви събития в календара, включително тези на приятели или колеги. Така приложението може да има възможност да споделя или запазва данните от календара ви, независимо дали са поверителни."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Разрешава на приложението да чете настройките за синхронизиране на профил. Например това може да бъде използвано за активиране на синхронизирането на приложението Хора с даден профил."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"четене на статистическите данни за синхронизиране"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Разрешава на приложението да чете статистическите данни за синхронизирането на профил, включително историята на синхронизираните събития и обема на информацията, която се синхронизира."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"четене на думите, които сте добавили в речника"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Разрешава на приложението да чете всички думи, имена и фрази, които потребителят може да е съхранил в потребителския речник."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"добавяне на думи в дефинирания от потребителя речник"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Разрешава на приложението да записва нови думи в потребителския речник."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"четене на съдърж. от USB хран. ви"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"четене на съдържанието от SD картата ви"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Разрешава на прил. да чете съдърж. на USB."</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 3d4d800..3b82a6c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"অবস্থান"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"এই ডিভাইসের অবস্থানে অ্যাক্সেস করুন"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"আপনার সামাজিক তথ্য"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"আপনার পরিচিতিগুলি এবং সামাজিক পরিচিতিগুলি সম্পর্কিত তথ্যে সরাসরি অ্যাক্সেস৷"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ক্যালেন্ডার"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস করুন"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS বার্তাগুলি পাঠান এবং দেখুন"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"সঞ্চয়স্থান"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"আপনার ডিভাইসে ফটো, মিডিয়া এবং ফাইলগুলিতে অ্যাক্সেস করুন"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"ব্যবহারকারীর অভিধান"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ব্যবহারকারীর অভিধানে শব্দগুলিকে পড়ুন এবং লিখুন৷"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"বুকমার্কগুলি এবং ইতিহাস"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"বুকমার্কগুলি এবং ব্রাউজারের ইতিহাসে সরাসরি অ্যাক্সেস৷"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"মাইক্রোফোন"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"অডিও রেকর্ড করুন"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ক্যামেরা"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ছবি তুলুন এবং ভিডিও রেকর্ড করুন"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ফোন"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ফোন কলগুলি করুন এবং পরিচালনা করুন"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"সেন্সরগুলি"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"আপনার গুরুত্বপূর্ণ লক্ষণ এবং শারীরিক ক্রিয়াকলাপের সম্পর্কে তথ্য অ্যাক্সেস করুন"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"বডি সেন্সরগুলি"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"আপনার অত্যাবশ্যক লক্ষণগুলির সম্পর্কে সেন্সর ডেটা অ্যাক্সেস করে"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর সামগ্রী পুনরুদ্ধার করে"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপনি ইন্টারঅ্যাক্ট করছেন এমন একটি উইন্ডোর সামগ্রীকে সযত্নে নিরীক্ষণ করে৷"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ইনকামিং ও আউটগোয়িং কলগুলি সম্পর্কিত ডেটা সহ আপনার ট্যাবলেটের কল লগ পরিবর্তন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি এটিকে আপনার কল লগ মুছে দিতে বা পরিবর্তন করতে ব্যবহার করতে পারে৷"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ইনকামিং ও আউটগোয়িং কলগুলি সম্পর্কিত ডেটা সহ আপনার টিভির কল লগ পরিবর্তন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি এটিকে আপনার কল লগ মুছে দিতে বা পরিবর্তন করতে ব্যবহার করতে পারে৷"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ইনকামিং ও আউটগোয়িং কলগুলি সম্পর্কিত ডেটা সহ আপনার ফোনের কল লগ পরিবর্তন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি এটিকে আপনার কল লগ মুছে দিতে বা পরিবর্তন করতে ব্যবহার করতে পারে৷"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"আপনার নিজের পরিচিতি কার্ড পড়ুন"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"অ্যাপ্লিকেশানটিকে আপনার নাম এবং পরিচিতি তথ্যের মতো আপনার ডিভাইসে সংরক্ষিত ব্যক্তিগত প্রোফাইলের তথ্য পড়ার অনুমতি দেয়৷ এর মানে হল এই অ্যাপ্লিকেশানটি আপনাকে শনাক্ত করতে পারে এবং আপনার প্রোফাইলের তথ্য অন্যদের পাঠাতে পারে৷"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"আপনার নিজস্ব পরিচিতি কার্ড সংশোধন করুন"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"অ্যাপ্লিকেশানটিকে আপনার ডিভাইসে সংরক্ষিত ব্যক্তিগত প্রোফাইলের তথ্য যেমন আপনার নাম এবং পরিচিতি তথ্য পড়ার অনুমতি দেয়৷ এর মানে হল এই অ্যাপ্লিকেশানটি আপনাকে শনাক্ত করতে পারে এবং আপনার প্রোফাইলের তথ্য অন্যদের পাঠাতে পারে৷"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"শরীরের সেন্সর (হার্ট রেট মনিটারের মত)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"অ্যাপ্লিকেশানটিকে আপনার শারীরিক অবস্থা যেমন, আপনার হৃৎস্পন্দন পর্যবেক্ষণ করে এমন সেন্সরগুলি অ্যাক্সেস করতে মঞ্জুরি দেয়।"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"আপনার সামাজিক স্ট্রীম পড়ে"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"অ্যাপ্লিকেশানটিকে আপনার এবং আপনার বন্ধুদের থেকে সামাজিক আপডেটগুলিতে অ্যাক্সেস এবং সিঙ্ক করতে দেয়৷ তথ্য ভাগ করার সময় সতর্ক থাকুন -- এই অ্যাপ্লিকেশানটিকে গোপনীয়তা নির্বিশেষে সামাজিক নেটওয়ার্কগুলিতে আপনি এবং আপনার বন্ধুদের মধ্যে যোগাযোগগুলি পড়তে দেয়৷ দ্রষ্টব্য: এই অনুমতি সমস্ত সামাজিক নেটওয়ার্কে বলবৎ নাও হতে পারে৷"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"আপনার সামাজিক স্ট্রীমে লেখে"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"অ্যাপ্লিকেশানটিকে আপনার বন্ধুদের থেকে সামাজিক আপডেটগুলিতে প্রদর্শন করতে দেয়৷ তথ্য ভাগ করার সময় সতর্ক থাকুন -- এই অ্যাপ্লিকেশানটিকে এমন ধরনের বার্তা তৈরি করতে অনুমতি দেয় যা দেখে মনে হবে কোনো বন্ধু আপনাকে পাঠিয়েছে৷ দ্রষ্টব্য: এই অনুমতি সমস্ত সামাজিক নেটওয়ার্কে বলবৎ নাও হতে পারে৷"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ক্যালেন্ডার ইভেন্ট, তার সাথে গোপন তথ্যও পড়ে"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"আপনার ট্যাবলেটে সঞ্চিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে অ্যাপ্লিকেশানটিকে মঞ্জুর করে, এর মধ্যে বন্ধু ও সহকর্মীদেরগুলিও অন্তর্ভুক্ত৷ এটি গোপনীয়তা বা সংবেদনশীলতা নির্বিশেষে আপনার ক্যালেন্ডার ডেটা ভাগ ও সংরক্ষণ করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করতে পারে৷"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"অ্যাপ্লিকেশানটিকে আপনার টিভিতে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্টগুলি পড়তে দেয়, যার মধ্যে বন্ধুদের বা সহকর্মীদের ক্যালেন্ডার ইভেন্টগুলিও অন্তর্ভুক্ত থাকে৷ গোপনীয়তা বা সংবেদনশীলতা নির্বিশেষে এটি অ্যাপ্লিকেশানটিকে আপনার ক্যালেন্ডার ডেটা ভাগ করতে বা সংরক্ষণ করার অনুমতি দিতে পারে৷"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"একটি অ্যাকাউন্টের জন্য সমন্বয় সেটিংস সংশোধন করতে একটি অ্যাপ্লিকেশানকে অনুমতি দেয়৷ উদাহরণস্বরূপ, এটি একটি অ্যাকাউন্টের সাথে People অ্যাপ্লিকেশানের সমন্বয় সক্ষম করার কাজে ব্যবহৃত হতে পারে৷"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"সিঙ্ক পরিসংখ্যান পড়ে"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"অ্যাপ্লিকেশানটিকে একটি অ্যাকাউন্টের জন্য কতটা ডেটা সিঙ্ক হয়েছে এবং সিঙ্ক করা ইভেন্টের ইতিহাস সহ সিঙ্কের স্থিতি পড়ার অনুমতি দেয়৷"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"আপনার অভিধানে যোগ করা শব্দগুলি পড়ুন"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"অ্যাপ্লিকেশানটিকে সমস্ত শব্দ, নাম এবং ব্যবহারকারী দ্বারা ব্যবহারকারী অভিধানে সংরক্ষিত বাক্যাংশ পড়ার অনুমতি দেয়৷"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ব্যবহারকারী নির্ধারিত অভিধানে শব্দ যোগ করুন"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"অ্যাপ্লিকেশানকে ব্যবহারকারীর অভিধানের মধ্যে নতুন শব্দ লিখতে দেয়৷"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"আপনার USB সংগ্রহস্থলের সামগ্রীগুলিকে পড়ুন"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"আপনার SD কার্ডের সামগ্রীগুলিকে পড়ুন"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"অ্যাপ্লিকেশানটিকে আপনার USB সঞ্চয়স্থানের সামগ্রীগুলিকে পড়ার অনুমতি দেয়৷"</string>
@@ -871,7 +852,7 @@
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="6876518925844129331">"সবগুলি নির্বাচন করুন"</string>
- <string name="cut" msgid="3092569408438626261">"ছেদন"</string>
+ <string name="cut" msgid="3092569408438626261">"কাটুন"</string>
<string name="copy" msgid="2681946229533511987">"অনুলিপি"</string>
<string name="paste" msgid="5629880836805036433">"আটকান"</string>
<string name="replace" msgid="5781686059063148930">"প্রতিস্থাপন করুন..."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 81ced84..6fdce0b 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>
@@ -168,7 +167,7 @@
<string name="low_memory" product="default" msgid="3475999286680000541">"L\'emmagatzematge del telèfon és ple. Suprimeix uns quants fitxers per alliberar espai."</string>
<string name="ssl_ca_cert_warning" msgid="5848402127455021714">"És possible que la xarxa estigui supervisada"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Per un tercer desconegut"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Administrador del perfil de la feina"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Administrador del perfil professional"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Per <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"S\'ha suprimit el perfil professional"</string>
<string name="work_profile_deleted_description" msgid="6305147513054341102">"S\'ha suprimit el perfil professional perquè no s\'ha detectat cap aplicació d\'administració."</string>
@@ -225,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicació"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accedeix a la ubicació del dispositiu"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informació social"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accés directe a informació sobre els teus contactes i sobre les teves connexions socials."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendari"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedir al calendari"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar i llegir missatges SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Emmagatzematge"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accedir a fotos, contingut multimèdia i fitxers del dispositiu"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionari de l\'usuari"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Llegir o escriure paraules al diccionari de l\'usuari."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadors i historial"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accés directe a l\'historial de marcadors i de navegació."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micròfon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrar àudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Càmera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fer fotos i vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telèfon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar les trucades telefòniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accedir a informació sobre els signes vitals i l\'activitat física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensors corporals"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedir a les dades del sensor sobre els signes vitals"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de la finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb què estàs interaccionant."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar Exploració tàctil"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permet que l\'aplicació modifiqui el registre de trucades de la teva tauleta, incloses les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses ho utilitzin per eliminar o per modificar el teu registre de trucades."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permet que l\'aplicació modifiqui el registre de trucades del televisor, com ara les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses l\'utilitzin per esborrar o modificar les dades del registre de trucades."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permet que l\'aplicació modifiqui el registre de trucades del teu telèfon, incloses les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses ho utilitzin per eliminar o per modificar el teu registre de trucades."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lectura targeta de contacte"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permet que l\'aplicació pugui llegir informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que l\'aplicació et pot identificar i enviar la informació del teu perfil a altres persones."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modificació targeta contacte"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet que l\'aplicació pugui canviar o afegir informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que l\'aplicació et pot identificar i enviar la informació del teu perfil a altres persones."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensors corp. (monitors freq. cardíaca)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet que l\'aplicació accedeixi a les dades dels sensors que supervisen el teu estat físic, com ara la freqüència cardíaca."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"llegeix el teu tauler d\'activitat social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet que l\'aplicació accedeixi i sincronitzi actualitzacions socials teves i dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació llegeixi comunicacions entre tu i els teus amics a les xarxes socials, independentment de la confidencialitat. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escriu al tauler d\'activitat social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permet que l\'aplicació mostri actualitzacions socials dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació produeixi missatges que pot semblar que provinguin d\'un amic. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"llegeix els esdeveniments del calendari més informació confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permet que l\'aplicació llegeixi tots els esdeveniments del calendari emmagatzemats a la tauleta, inclosos els dels amics o dels companys de feina. Aquesta acció pot permetre que l\'aplicació comparteixi o desi les dades del teu calendari, sense tenir en compte la confidencialitat."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permet que l\'aplicació llegeixi tots els esdeveniments del calendari emmagatzemats al televisor, com ara els dels amics o els dels companys de feina. Amb aquesta acció, l\'aplicació pot compartir o desar les dades del teu calendari sense tenir en compte la confidencialitat o la sensibilitat."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet que una aplicació modifiqui la configuració de sincronització d\'un compte. Per exemple, aquesta acció es pot fer servir per activar la sincronització de l\'aplicació Persones amb un compte."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"llegir les estadístiques de sincronització"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet que una aplicació llegeixi les estadístiques de sincronització d\'un compte, inclòs l\'historial d\'esdeveniments sincronitzats i quantes dades se sincronitzen."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lectura dels termes que afegeixes al diccionari"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permet que l\'aplicació llegeixi les paraules, els noms i les frases que l\'usuari pot haver emmagatzemat al seu diccionari."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"afegeix paraules al diccionari definit per l\'usuari"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet que l\'aplicació escrigui paraules noves al diccionari de l\'usuari."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"consultar contingut emmagatzematge USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lectura del contingut de la targeta SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permet que l\'aplicació llegeixi el contingut de l\'emmagatzematge USB."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8b92c84..d3ddf6a 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"přístup k poloze tohoto zařízení"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informace o vašich kontaktech a sociálních sítích"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Přímý přístup k informacím o vašich kontaktech a sociálních propojeních"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"přístup ke kalendáři"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"odesílání a zobrazení zpráv SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Úložiště"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"přístup k fotkám, médiím a souborům na zařízení"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Uživatelský slovník"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čtení a zápis slov v uživatelském slovníku"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Záložky a historie"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Přímý přístup k záložkám a historii prohlížení"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"nahrávání zvuku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"pořizování fotografií a nahrávání videa"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"uskutečňování a správa telefonních hovorů"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"přístup k informacím o životních funkcích a fyzické aktivitě"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tělesné senzory"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"přístup k údajům snímačů vašich životních funkcí"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načíst obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Můžete prozkoumat obsah okna, se kterým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnout funkci Prozkoumání dotykem"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje aplikaci upravovat seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Umožňuje aplikaci upravovat seznam hovorů vaší televize včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje aplikaci upravovat seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"čtení vaší vlastní vizitky"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Umožňuje aplikaci číst údaje v osobním profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"úprava vaší vlastní vizitky"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje aplikaci změnit nebo přidat údaje osobního profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"tělesné senzory (například snímače tepu)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Umožňuje aplikaci používat data ze senzorů, které sledují vaši fyzickou kondici, například tepovou frekvenci."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čtení vašeho sociálního streamu"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje aplikaci získat přístup k sociálním aktualizacím od vašich přátel a synchronizaci těchto aktualizací. Při sdílení informací buďte opatrní – toto oprávnění umožňuje aplikaci číst komunikaci mezi vámi a vašimi přáteli v sociálních sítích bez ohledu na její důvěrnost. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zápis do sociálního streamu"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Umožňuje aplikaci zobrazit sociální aktualizace od vašich přátel. Při sdílení informací buďte opatrní – aplikace s tímto oprávněním může vytvářet zprávy, které zdánlivě pochází od vašich přátel. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čtení událostí kalendáře a důvěrné informace"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Umožňuje aplikaci číst všechny události kalendáře uložené v tabletu, včetně událostí přátel nebo spolupracovníků. Aplikace s tímto oprávněním může sdílet nebo ukládat údaje v kalendáři bez ohledu na důvěrnost nebo citlivost těchto údajů."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Umožňuje aplikaci číst veškeré události v kalendáři uložené v televizi, a to včetně událostí přátel a spolupracovníků. Aplikaci to může umožnit sdílet nebo ukládat data kalendáře bez ohledu na jejich důvěrnost či citlivost."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Umožňuje aplikaci změnit nastavení synchronizace v účtu. Pomocí tohoto oprávnění lze například zapnout synchronizaci aplikace Lidé s účtem."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"čtení statistických údajů o synchronizaci"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Umožňuje aplikaci číst statistické informace o synchronizaci v účtu, včetně historie uskutečněných synchronizací a informací o množství synchronizovaných dat."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"čtení výrazů přidaných do slovníku"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Umožňuje aplikaci číst slova, jména a fráze, která uživatel mohl uložit do svého slovníku."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"přidávání slov do slovníku definovaného uživatelem"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje aplikaci zapisovat nová slova do uživatelského slovníku."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"čtení obsahu v úložišti USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čtení obsahu na kartě SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Umožňuje aplikaci čtení obsahu USB."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index af6aa5a..4c1eac0 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"adgang til enhedens placering"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Dine sociale oplysninger"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte adgang til oplysninger om dine kontaktpersoner og sociale forbindelser."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"Send og se sms-beskeder"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"Få adgang til billeder, medier og filer på din enhed"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Brugerordbog"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Læse eller skrive ord i brugerordbogen."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bogmærker og historik"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte adgang til bogmærker og browserhistorik."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"optage lyd"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tage billeder og optage video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"foretage og administrere telefonopkald"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Få adgang til oplysninger om dine livstegn og din fysiske aktivitet"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kropssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få adgang til sensordata om dine livstegn"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente indholdet i vinduet"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tillader, at appen ændrer din tablets opkaldsliste, f.eks. data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldsliste."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Giver appen lov til at ændre opkaldslisten på dit tv, herunder data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldsliste."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tillader, at appen ændrer telefonens opkaldsliste, f.eks. data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldsliste."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"læse dit eget kontaktkort"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Tillader, at appen kan læse de personlige profiloplysninger, der er gemt på din enhed, f.eks. dit navn og dine kontaktoplysninger. Det betyder, at appen kan identificere dig og sende dine profiloplysninger til andre."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ændre dit eget kontaktkort"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tillader, at appen kan ændre eller tilføje oplysninger i din personlige profil, der er gemt på din enhed, f.eks. dit navn eller dine kontaktoplysninger. Dette betyder, at andre apps kan identificere dig og sende profiloplysninger til andre."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kropssensorer (f.eks. pulsmålere)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Giver appen adgang til data fra sensorer, der overvåger din fysiske tilstand, f.eks. din puls."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"læse din sociale strøm"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tillader, at appen kan få adgang til og synkronisere sociale opdateringer fra dig og dine venner. Vær forsigtig, når du deler oplysninger – med denne tilladelse kan appen læse kommunikation mellem dig og dine venner på sociale netværk, uanset fortrolighed. Bemærk! Denne tilladelse håndhæves muligvis ikke på alle sociale netværk."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sociale strøm"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tillader, at appen kan vise sociale opdateringer fra dine venner. Vær forsigtig, når du deler oplysninger – med denne tilladelse kan appen producere meddelelser, der kan synes at komme fra en ven. Bemærk! Denne tilladelse håndhæves muligvis ikke på alle sociale netværk."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"læse kalenderbegivenheder og fortrolige oplysninger"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tillader, at appen kan læse alle de kalenderbegivenheder, der er gemt på din tablet, f.eks. venners eller kollegers. Med denne tilladelse kan appen dele eller gemme dine kalenderdata, uanset fortrolighed eller følsomhed."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Giver appen lov til at læse alle kalenderbegivenheder, der er gemt på dit tv, herunder begivenheder tilhørende venner og kolleger. Dette kan give appen lov til at dele eller gemme dine kalenderdata, uanset om de er fortrolige eller følsomme."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Tillader, at en app kan ændre synkroniseringsindstillingerne for en konto. Denne tilladelse kan f.eks. anvendes til at aktivere synkronisering af appen Personer med en konto."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"læse synkroniseringsstatistikker"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Tillader, at en app kan læse synkroniseringsstatistikkerne for en konto, f.eks. historikken for synkroniserede begivenheder og hvor meget data der synkroniseres."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"læse termer, som du har føjet til ordbogen"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Tillader, at appen kan læse alle ord, navne og sætninger, som brugeren har gemt i brugerordbogen."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"føj ord til den brugerdefinerede ordbog"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tillader, at appen kan skrive nye ord i brugerordbogen."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"læse USB-lagerets indhold"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"læse indholdet af dit SD-kort"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Tillader, at appen læser indholdet på dit USB-lager."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8e9a6ac..d38cb3f 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"Auf den Standort Ihres Geräts zugreifen"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ihre sozialen Informationen"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkter Zugriff auf Informationen über Ihre Kontakte und sozialen Verbindungen"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"Auf Kalender zuzugreifen"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS senden und abrufen"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Speicher"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"Auf Fotos, Medien und Dateien auf Ihrem Gerät zugreifen"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Mein Wörterbuch"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Wörter in Mein Wörterbuch lesen oder schreiben"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Lesezeichen und Verlauf"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkter Zugriff auf Lesezeichen und Browserverlauf"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"Audio aufzunehmen"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"Bilder und Videos aufzunehmen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"Telefonanrufe zu tätigen und zu verwalten"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Auf Informationen zu Ihren Vitaldaten und physischen Aktivitäten zugreifen"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Körpersensoren"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Auf Sensordaten zu Ihren Vitaldaten zugreifen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters mit dem Sie interagieren werden abgerufen."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen & Entdecken\" aktivieren"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ermöglicht der App, die Anrufliste Ihres Fernsehers zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"Ihre Kontaktkarten lesen"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"Ihre Kontaktkarten ändern"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"Körpersensoren (wie Pulsmonitore)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ermöglicht der App, auf Daten von Sensoren zuzugreifen, die Ihre körperliche Verfassung überwachen, beispielsweise Ihren Puls"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ermöglicht der App, auf Updates aus sozialen Netzwerken von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Seien Sie vorsichtig, wenn Sie Informationen teilen: Der App wird erlaubt, die Kommunikation zwischen Ihnen und Ihren Freunden in sozialen Netzwerken zu lesen, unabhängig von der Vertraulichkeit der kommunizierten Informationen. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"In sozialem Stream schreiben"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Ermöglicht der App, Updates aus sozialen Netzwerken von Ihren Freunden einzublenden. Seien Sie vorsichtig, wenn Sie Informationen teilen: Die App kann damit Nachrichten erstellen, die so erscheinen, als stammten Sie von einem Freund. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"Kalendertermine sowie vertrauliche Informationen lesen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ermöglicht der App, alle auf Ihrem Tablet gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise Ihre Kalenderdaten unabhängig von der Vertraulichkeit weiterleiten oder speichern."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ermöglicht der App, alle auf Ihrem Fernseher gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise Ihre Kalenderdaten unabhängig von der Vertraulichkeit teilen oder speichern."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ermöglicht der App, die Synchronisierungseinstellungen eines Kontos zu ändern. Dies kann beispielsweise dazu verwendet werden, die Synchronisierung von Kontakten mit einem Konto zu aktivieren."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Synchronisierungsstatistiken lesen"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ermöglicht der App, die Synchronisierungsstatistiken eines Kontos zu lesen, einschließlich des Verlaufs von Synchronisierungsereignissen und der Menge synchronisierter Daten."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"Begriffe lesen, die Sie zum Wörterbuch hinzugefügt haben"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Ermöglicht der App, alle Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"Wörter zu meinem Wörterbuch hinzufügen"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ermöglicht der App, neue Einträge zum Nutzerwörterbuch hinzuzufügen"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB-Speicherinhalte lesen"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD-Karteninhalte lesen"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Ermöglicht der App, den USB-Speicher zu lesen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8d1779c..2ac26fe 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Τοποθεσία"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"πρόσβαση στην τοποθεσία αυτής της συσκευής"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Οι κοινωνικές πληροφορίες σας"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Άμεση πρόσβαση σε πληροφορίες σχετικά με τις επαφές και τις κοινωνικές συνδέσεις σας."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Ημερολόγιο"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"πρόσβαση στο ημερολόγιό σας"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"αποστολή και προβολή μηνυμάτων SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Αποθηκευτικός χώρος"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"πρόσβαση στις φωτογραφίες, τα πολυμέσα και τα αρχεία στη συσκευή σας"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Λεξικό χρήστη"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ανάγνωση ή εγγραφή λέξεων στο λεξικό χρήστη."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Σελιδοδείκτες και ιστορικό"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Άμεση πρόσβαση σε σελιδοδείκτες και ιστορικού προγράμματος περιήγησης."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Μικρόφωνο"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"εγγραφή ήχου"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Κάμερα"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"λήψη φωτογραφιών και εγγραφή βίντεο"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Τηλέφωνο"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"πραγματοποίηση και διαχείριση τηλεφωνικών κλήσεων"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Αισθητήρες"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"πρόσβαση σε πληροφορίες σχετικά με τις ζωτικές ενδείξεις και τη σωματική δραστηριότητα"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Αισθητήρες σώματος"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"πρόσβαση στα δεδομένα αισθητήρα σχετικά με τις ζωτικές ενδείξεις σας"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ανάκτηση του περιεχομένου του παραθύρου"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Έλεγχος του περιεχομένου ενός παραθύρου με το οποίο αλληλεπιδράτε."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ενεργοποίηση της \"Εξερεύνησης με άγγιγμα\""</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του tablet σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων της τηλεόρασής σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Κακόβουλες εφαρμογές μπορεί να χρησιμοποιήσουν αυτήν τη δυνατότητα, για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του τηλεφώνου σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ανάγνωση της κάρτας επαφής σας"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Επιτρέπει στην εφαρμογή την ανάγνωση προσωπικών πληροφοριών προφίλ οι οποίες είναι αποθηκευμένες στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι η εφαρμογή μπορεί να σας αναγνωρίσει και να στείλει τις πληροφορίες του προφίλ σας σε άλλους."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"τροποποίηση κάρτας επαφής"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Επιτρέπει στην εφαρμογή την αλλαγή ή την προσθήκη προσωπικών πληροφοριών προφίλ οι οποίες είναι αποθηκευμένες στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι η εφαρμογή μπορεί να σας αναγνωρίσει και να στείλει τις πληροφορίες του προφίλ σας σε άλλα άτομα."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"αισθητήρες λειτουργιών (π.χ. καρδιακό ρυθμό)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στα δεδομένα των αισθητήρων που παρακολουθούν τη φυσική σας κατάσταση, όπως τον καρδιακό ρυθμό σας."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"διαβάστε τη ροή σας κοινωνικών δικτύων"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Επιτρέπει στην εφαρμογή την πρόσβαση και το συγχρονισμό κοινωνικών ενημερώσεων από εσάς και τους φίλους σας. Θα πρέπει να είστε προσεκτικοί όταν μοιράζεστε πληροφορίες -- αυτό δίνει τη δυνατότητα στην εφαρμογή να διαβάζει τις επικοινωνίες ανάμεσα σε εσάς και τους φίλους σας σε κοινωνικά δίκτυα, ανεξάρτητα από το επίπεδο εμπιστευτικότητας. Σημείωση: αυτή η άδεια ίσως να μην μπορεί να εφαρμοστεί σε όλα τα κοινωνικά δίκτυα."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"γράψτε στη ροή σας κοινωνικών δικτύων"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Επιτρέπει στην εφαρμογή την προβολή κοινωνικών ενημερώσεων από τους φίλους σας. Θα πρέπει να είστε προσεκτικοί όταν μοιράζεστε πληροφορίες -- αυτό δίνει τη δυνατότητα στην εφαρμογή να δημιουργεί μηνύματα που μπορεί να φαίνεται ότι προέρχονται από κάποιο φίλο. Σημείωση: αυτή η άδεια ίσως να μην μπορεί να εφαρμοστεί σε όλα τα κοινωνικά δίκτυα."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ανάγνωση συμβάντων ημερολογίου και εμπιστευτικών πληροφοριών"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Επιτρέπει στην εφαρμογή την ανάγνωση όλων των συμβάντων ημερολογίου που είναι αποθηκευμένα στο tablet σας, συμπεριλαμβανομένων εκείνων των φίλων ή των συναδέλφων σας. Αυτό μπορεί να δίνει τη δυνατότητα στην εφαρμογή να μοιράζεται ή να αποθηκεύει τα δεδομένα του ημερολογίου σας, ανεξάρτητα από το βαθμό εμπιστευτικότητας ή ευαισθησίας τους."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Επιτρέπει στην εφαρμογή να διαβάζει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στην τηλεόρασή σας, συμπεριλαμβανομένων εκείνων από τους φίλους ή τους συναδέλφους σας. Αυτό μπορεί να επιτρέψει στην εφαρμογή να μοιράζεται ή να αποθηκεύει τα δεδομένα ημερολογίου, ανεξαρτήτως εμπιστευτικότητας ή ευαισθησίας."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Επιτρέπει σε μια εφαρμογή την τροποποίηση των ρυθμίσεων συγχρονισμού για έναν λογαριασμό. Για παράδειγμα, αυτό μπορεί να χρησιμοποιηθεί για να ενεργοποιηθεί ο συγχρονισμός της εφαρμογής \"Άτομα\" με έναν λογαριασμό."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ανάγνωση στατιστικών συγχρονισμού"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Επιτρέπει σε μια εφαρμογή την ανάγνωση των στατιστικών στοιχείων συγχρονισμού για έναν λογαριασμό, συμπεριλαμβανομένων του ιστορικού των συμβάντων συγχρονισμού και του όγκου των δεδομένων που συγχρονίζονται."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ανάγνωση όρων που έχετε προσθέσει στο λεξικό"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Επιτρέπει στην εφαρμογή την ανάγνωση όλων των λέξεων, των ονομάτων και φράσεων, τα οποία ο χρήστης ενδέχεται να έχει αποθηκεύσει στο λεξικό χρήστη."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"προσθήκη λέξεων στο καθορισμένο από το χρήστη λεξικό"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Επιτρέπει στην εφαρμογή την εγγραφή νέων λέξεων στο λεξικό χρήστη."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ανάγν. περιεχ. αποθηκ. χώρ.USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ανάγνωση του περιεχομένου της κάρτας SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Επιτρέπει στην εφαρμογή την ανάγνωση του περιεχομένου του αποθηκευτικού σας χώρου USB."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 7e89393..3a1f74c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"send and view SMS messages"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"access photos, media and files on your device"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"read your own contact card"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Allows the app to read personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"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>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"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>
<string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Allows the app to read all calendar events stored on your tablet, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Allows the app to read all calendar events stored on your TV, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable syncing of the People app with an account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"read terms you added to the dictionary"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Allows the app to read all words, names and phrases that the user may have stored in the user dictionary."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"add words to user-defined dictionary"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Allows the app to write new words into the user dictionary."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"read the contents of your USB storage"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"read the contents of your SD card"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Allows the app to read the contents of your USB storage."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 7e89393..3a1f74c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"send and view SMS messages"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"access photos, media and files on your device"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"read your own contact card"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Allows the app to read personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"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>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"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>
<string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Allows the app to read all calendar events stored on your tablet, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Allows the app to read all calendar events stored on your TV, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable syncing of the People app with an account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"read terms you added to the dictionary"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Allows the app to read all words, names and phrases that the user may have stored in the user dictionary."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"add words to user-defined dictionary"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Allows the app to write new words into the user dictionary."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"read the contents of your USB storage"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"read the contents of your SD card"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Allows the app to read the contents of your USB storage."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7e89393..3a1f74c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"send and view SMS messages"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"access photos, media and files on your device"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"access information about your vital signs and physical activity"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Body Sensors"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"access sensor data about your vital signs"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Allows the app to modify your TV\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"read your own contact card"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Allows the app to read personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"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>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"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>
<string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Allows the app to read all calendar events stored on your tablet, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Allows the app to read all calendar events stored on your TV, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable syncing of the People app with an account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"read terms you added to the dictionary"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Allows the app to read all words, names and phrases that the user may have stored in the user dictionary."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"add words to user-defined dictionary"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Allows the app to write new words into the user dictionary."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"read the contents of your USB storage"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"read the contents of your SD card"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Allows the app to read the contents of your USB storage."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d3a4d61..80a7fc3 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acceso a la ubicación de este dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Tu información social"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceso directo a información sobre tus contactos y conexiones sociales"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder al calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar y ver mensajes SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Espacio de almacenamiento"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"acceder a las fotos, el contenido multimedia y los archivos del dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionario del usuario"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"leer o escribir palabras en el diccionario del usuario"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e historial"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceso directo a marcadores e historial del navegador"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tomar fotografías y grabar videos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"realizar y administrar llamadas telefónicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acceder a información acerca de tus signos vitales y la actividad física"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder a los datos del sensor acerca de tus signos vitales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de las ventanas"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de la ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la Exploración táctil"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite que la aplicación modifique el registro de llamadas de la tablet, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite que la aplicación modifique el registro de llamadas de la TV, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite que la aplicación modifique el registro de llamadas del dispositivo, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"leer tarjeta contacto propia"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite que la aplicación consulte la información del perfil personal almacenada en el dispositivo, como el nombre o la información de contacto, lo que significa que la aplicación puede identificar al usuario y enviar la información de su perfil a otros usuarios."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modif. tarjeta contacto propia"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que la aplicación modifique la información del perfil personal almacenada en el dispositivo, como el nombre o la información de contacto, o que agregue contenido a esa información. Esto significa que puede identificarte y enviar la información de tu perfil a otros usuarios."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporales (frec. card)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la aplicación acceda a datos de sensores que controlan tu condición física, como el ritmo cardíaco."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Lectura de tu muro social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que la aplicación acceda a las actualizaciones de tus redes sociales y las de tus amigos, y que las sincronice. Ten cuidado al compartir información, ya que la aplicación puede utilizar este permiso para leer las conversaciones que tengas con tus amigos en las redes sociales sin tener en cuenta si son confidenciales. Nota: Este permiso no se puede utilizar en todas las redes sociales."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Escritura en tu muro social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite que la aplicación muestre actualizaciones de las redes sociales de tus amigos. Ten cuidado al compartir información, ya que la aplicación puede generar mensajes que parezcan proceder de amigos. Nota: Este permiso no se puede utilizar en todas las redes sociales."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"leer eventos de calendario e información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite que la aplicación consulte todos los eventos de calendario almacenados en la tablet, incluidos los de amigos y compañeros de trabajo. La aplicación puede utilizar este permiso para compartir o guardar datos del calendario del usuario sin tener en cuenta si son privados o confidenciales."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite que la aplicación lea todos los eventos de calendario almacenados en la TV, incluidos aquellos de amigos o colegas. Esta opción puede permitir que la aplicación comparta o guarde datos de calendario, independientemente de la confidencialidad o la privacidad."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite que la aplicación modifique la configuración de sincronización de una cuenta. Este permiso se puede utilizar, por ejemplo, para activar la sincronización de la aplicación Personas con una cuenta."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"leer estadística de sincronización"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite que la aplicación consulte las estadísticas de sincronización de una cuenta, por ejemplo, el historial de eventos sincronizados y la cantidad de datos sincronizados."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"leer los términos que agregaste al diccionario"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite que la aplicación consulte cualquier palabra, nombre o frase que el usuario haya almacenado en su diccionario."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"agregar palabras en el diccionario definido por el usuario"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite que la aplicación ingrese palabras nuevas en el diccionario del usuario."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"leer contenido de disp. USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"leer el contenido de tu tarjeta SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite leer contenido de USB."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index baf4601..84fecfc 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acceder a la ubicación de este dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Tu información social"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceder directamente a la información de tus contactos y tus conexiones sociales"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder a tu calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar y ver mensajes SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Almacenamiento"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"acceder a fotos, contenido multimedia y archivos de tu dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionario del usuario"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Leer o escribir palabras en el diccionario del usuario."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e historial"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceder directamente a los marcadores y al historial del navegador"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"hacer fotos y grabar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"hacer y administrar llamadas de teléfono"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acceder a información sobre tus constantes vitales y tu actividad física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporales"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder a datos del sensor sobre tus constantes vitales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de la ventana"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de una ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la exploración táctil"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite que la aplicación modifique el registro de llamadas del tablet, incluidos datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite que la aplicación modifique el registro de llamadas de la TV, incluidos datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden utilizar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite que la aplicación modifique el registro de llamadas del teléfono, incluidos datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"consultar tu propia tarjeta de contacto"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite que la aplicación consulte la información del perfil personal almacenada en el dispositivo (como el nombre o la información de contacto), lo que significa que la aplicación puede identificar al usuario y enviar la información de su perfil a otros usuarios."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modificar tu propia tarjeta de contacto"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que la aplicación modifique la información del perfil personal almacenada en el dispositivo (como el nombre o la información de contacto) o que añada contenido a esa información, lo que significa que puede identificar al usuario y enviar la información de su perfil a otros usuarios."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporales (como monitores de frecuencia cardíaca)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la aplicación acceda a datos de sensores que controlan tu condición física, como la frecuencia cardíaca."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"consulta tu actividad social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que la aplicación acceda a novedades de redes sociales tuyas y de tus amigos y las sincronice. Ten cuidado al compartir información, ya que la aplicación puede utilizar este permiso para leer conversaciones privadas con tus amigos en las redes sociales sin tener en cuenta si son confidenciales. Nota: este permiso no se puede utilizar en todas las redes sociales."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escribir en tu actividad social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite que la aplicación muestre novedades de redes sociales de tus amigos. Ten cuidado al compartir información, ya que la aplicación puede utilizar este permiso para generar mensajes que parezcan proceder de amigos. Nota: este permiso no se puede utilizar en todas las redes sociales."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"leer eventos de calendario e información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite que la aplicación consulte todos los eventos de calendario almacenados en el tablet, incluidos los de amigos y compañeros de trabajo. La aplicación puede utilizar este permiso para compartir o guardar datos del calendario del usuario sin tener en cuenta si son privados o confidenciales."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite que la aplicación lea los eventos de calendario almacenados en la TV, incluidos los eventos de amigos y compañeros de trabajo. Esto puede permitir a la aplicación compartir o guardar tus datos de calendario, independientemente de su nivel de privacidad o confidencialidad."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite que la aplicación modifique la configuración de sincronización de una cuenta. Este permiso se puede utilizar, por ejemplo, para habilitar la sincronización de la aplicación Contactos con una cuenta."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"leer estadísticas de sincronización"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite que la aplicación consulte las estadísticas de sincronización de una cuenta (por ejemplo, el historial de eventos sincronizados y la cantidad de datos sincronizados)."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"consultar términos que hayas añadido al diccionario"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite que la aplicación lea cualquier palabra, nombre o frase que el usuario haya almacenado en su diccionario."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"añadir palabras al diccionario definido por el usuario"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite que la aplicación escriba palabras nuevas en el diccionario de usuario."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"consultar el contenido del almacenamiento USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"consultar el contenido de la tarjeta SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite que la aplicación lea el contenido del almacenamiento USB."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 0eb270c..a04244f 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Asukoht"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"pääseda juurde selle seadme asukohale"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Teie sotsiaalne teave"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Otsene juurdepääs teie kontaktide teabele ja sotsiaalsetele sidemetele."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"juurdepääs kalendrile"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"saata ja vaadata SMS-sõnumeid"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Mäluruum"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"juurde pääseda seadmesse salvestatud fotodele, meediale ja failidele"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kasutaja sõnaraamat"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kasutaja sõnaraamatus sõnade lugemine ja nende sinna kirjutamine."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Järjehoidjad ja ajalugu"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Otsene juurdepääs järjehoidjatele ja brauseri ajaloole."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"heli salvestamine"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kaamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"pildistamine ja video salvestamine"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"helistamine ja telefonikõnede haldamine"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Andurid"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"juurde pääseda teabele eluliste näitajate ja füüsiliste tegevuste kohta"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kehaandurid"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"juurdepääs anduri andmetele teie eluliste näitajate kohta"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Akna sisu toomine"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tutvuge kasutatava akna sisuga."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Puudutusega sirvimise sisselülitamine"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lubab rakendusel muuta tahvelarvuti kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Lubab rakendusel muuta teleri kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lubab rakendusel muuta telefoni kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lugege oma kontaktikaarti"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Võimaldab rakendusel lugeda seadmesse salvestatud isiklikku profiiliteavet, näiteks teie nime ja kontaktteavet. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"muutke oma kontaktikaarti"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Võimaldab rakendusel muuta või lisada seadmesse salvestatud isiklikku profiiliteavet, näiteks teie nime ja kontaktteavet. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kehaandurid (nt pulsilugeja)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Lubab rakendusel hankida juurdepääsu andmetele anduritest, mis jälgivad teie füüsilist seisundit, nt südame löögisagedust."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Sotsiaalvoo lugemine"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Annab rakendusele juurdepääsu ja võimaldab sünkroonida teie ja teie sõprade sotsiaalseid värskendusi. Olge teabe jagamisel ettevaatlik – see võimaldab rakendusel lugeda teie suhtlusi sõpradega suhtlusvõrgustikes konfidentsiaalsusest hoolimata. Märkus: see luba ei pruugi jõustuda kõigis suhtlusvõrgustikes."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Sotsiaalvoogu kirjutamine"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Võimaldab rakendusel kuvada sõprade sotsiaalseid värskendusi. Olge teabe jagamisel ettevaatlik – see võimaldab rakendusel luua sõnumeid, mis võivad näida tulevat sõpradelt. Märkus: see luba ei pruugi jõustuda kõikides suhtlusvõrgustikes."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"kalendrisündmuste lugemine ja konfidentsiaalne teave"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Võimaldab rakendusel lugeda kõiki tahvelarvutisse salvestatud kalendrisündmusi, sh sõprade või töökaaslaste omi. See võib lubada rakendusel jagada või salvestada teie kalendriandmeid, hoolimata konfidentsiaalsusest või tundlikkusest."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Lubab rakendusel lugeda telerisse salvestatud kalendrisündmusi, sh sõprade ja töökaaslaste sündmusi. See võib võimaldada rakendusel kalendriandmeid jagada või salvestada, olenemata nende konfidentsiaalsusest või tundlikkusest."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Võimaldab rakendusel muuta konto sünkroonimisseadeid. Näiteks saab seda kasutada, et lubada rakenduse Inimesed sünkroonimine kontoga."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"loe sünkroonimisstatistikat"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Võimaldab rakendusel lugeda konto sünkroonimisstatistikat, sh sünkroonimissündmuste ajalugu ja sünkroonitud andmete hulka."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lugege termineid, mis te sõnastikku lisasite"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Võimaldab rakendusel lugeda kõiki sõnu, nimesid ja fraase, mille kasutaja on kasutaja sõnaraamatusse salvestanud."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"sõnade lisamine kasutaja määratletud sõnastikku"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Võimaldab rakendusel kirjutada kasutajasõnastikku uusi sõnu."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lugege USB-salvestusruumi sisu"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lugege oma SD-kaardi sisu"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Lubab rakendusel lugeda USB-salvestusruumi sisu."</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 0a2e8b3..3a35a07 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"Atzitu gailuaren kokapena"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sare sozialetako zure informazioa"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Zure kontaktuei eta konexio sozialei buruzko informaziorako sarbide zuzena."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"Atzitu egutegia"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS mezuak"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"Bidali eta ikusi SMS mezuak"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Memoria"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"Atzitu gailuko argazkiak, multimedia-elementuak eta fitxategiak"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Erabiltzailearen hiztegia"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Irakurri edo idatzi hitzak erabiltzaileek hiztegian."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Laster-markak eta historia"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Laster-marketarako eta arakatzailearen historiarako sarbide zuzena."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonoa"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"Grabatu audioa"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"Atera argazkiak eta grabatu bideoak"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"Egin eta kudeatu telefono-deiak"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sentsoreak"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"Atzitu zure bizi-konstanteei eta ariketa fisikoari buruzko informazioa"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Gorputz-sentsoreak"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Atzitu bizi-konstanteei buruzko sentsore-datuak"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Eskuratu leihoko edukia"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Arakatu irekita daukazun leihoko edukia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktibatu ukipen bidez arakatzeko eginbidea"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tabletaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Aplikazio gaiztoek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Telebistako deien erregistroa aldatzea baimentzen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Aplikazio gaiztoek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Telefonoaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Aplikazio gaiztoek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"zeure kontaktu-txartela irakurtzea"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Gailuan gordetako profil pertsonalaren informazioa irakurtzeko baimena ematen die aplikazioei; esaterako, zure izena eta harremanetan jartzeko informazioa. Horrek esan nahi du aplikazioek identifikatu egin zaitzaketela eta zure profil-informazioa besteei bidal diezaieketela."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"zeure kontaktu-txartela aldatzea"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Gailuan gordetako profil pertsonalaren informazioa aldatzeko baimena ematen dio; esaterako, zure izena eta harremanetan jartzeko informazioa. Horrek esan nahi du aplikazioak identifikatu egin zaitzakeela eta zure profil-informazioa besteei bidal diezaiekeela."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"Gorputzaren sentsoreak (adibidez, bihotz-erritmoaren monitoreak)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Zure egoera fisikoa kontrolatzen duten sentsoreetako datuak (adibidez, bihotz-maiztasuna) atzitzea baimentzen die aplikazioei."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"irakurri sare sozialetako korronteak"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Zure eta zure lagunen sare sozialetako eguneratzeak atzitzeko baimena ematen die aplikazioei. Kontuz partekatu informazioa; baimen honekin aplikazioak zure eta zure lagunen arteko sare sozialetako komunikazioak irakur ditzake, isilpekotasuna kontuan izan gabe. Oharra: baliteke baimen hori sare sozial guztiek ez aplikatzea."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"idatzi sare sozialetako korronteetan"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Zure lagunen sare sozialetako eguneratzeak bistaratzeko baimena ematen die aplikazioei. Kontuz partekatu informazioa; baimen honekin aplikazioak zure lagunenak direla diruditen mezuak sor ditzake. Oharra: baliteke baimen hori sare sozial guztiek ez aplikatzea."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"irakurri egutegiko gertaerak eta isilpeko informazioa"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tabletan gordetako egunkari-gertaera guztiak irakurtzeko baimena ematen die aplikazioei, lagunenak eta lankideenak barne. Horrela, aplikazioak egutegiko datuak parteka edo gorde ditzake, isilpekotasuna edo konfidentzialtasuna kontuan izan gabe."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Telebistan gordetako egutegiko gertaera guztiak irakurtzea baimentzen die aplikazioei, lagunenak eta lankideenak barne. Horrela, aplikazioek egutegiko datuak parteka edo gorde ditzakete, isilpekotasuna edo konfidentzialtasuna kontuan izan gabe."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Kontu baten sinkronizazio-ezarpenak aldatzeko baimena ematen die aplikazioei. Adibidez, Jendea aplikazioa kontu batekin sinkronizatzeko erabil daiteke."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"irakurri sinkronizazio-estatistikak"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Kontu baten sinkronizazio-estatistikak irakurtzeko baimena ematen dio; besteak beste, sinkronizazio-gertaeren historia eta sinkronizatutako datu kopurua."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"hiztegian gehitutako terminoak irakurtzea"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Erabiltzaile-hiztegian erabiltzaileak gordetako hitzak, izenak eta esaldiak irakurtzeko baimena ematen die aplikazioei."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"erabiltzaileak definitutako hiztegian hitzak gehitzea"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Erabiltzailearen hiztegian hitz berriak idaztea baimentzen die aplikazioei."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB memoriako edukia irakurtzea"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD txarteleko edukia irakurtzea"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"USB memoriako edukia irakurtzeko aukera ematen die aplikazioei."</string>
@@ -729,7 +710,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..36ce6e5 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"مکان"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"دسترسی به موقعیت مکانی این دستگاه"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"اطلاعات اجتماعی شما"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"مستقیم به اطلاعات مخاطبین و روابط اجتماعی دسترسی داشته باشید."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"تقویم"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"دسترسی به تقویم شما"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"پیامک"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ارسال و مشاهده پیامکها"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"حافظه"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"دسترسی به عکسها، رسانهها و فایلهای روی دستگاهتان"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"فرهنگ لغت کاربر"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"خواندن یا نوشتن کلمات در فرهنگ لغت کاربر."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"نشانکها و سابقه"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"مستقیم به نشانکها و سابقه مرور دسترسی داشته باشید."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"میکروفن"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ضبط صدا"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"دوربین"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"عکس گرفتن و فیلمبرداری"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"تلفن"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"برقراری و مدیریت تماسهای تلفنی"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"حسگرها"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"دسترسی به اطلاعات مربوط به علائم حیاتی و فعالیت فیزیکی شما"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"حسگرهای بدن"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"دسترسی به دادههای حسگر در رابطه با علائم حیاتی شما"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"محتوای پنجره را بازیابی کند"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"محتوای پنجرهای را که درحال تعامل با آن هستید بررسی میکند."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"فعالسازی کاوش لمسی"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"به برنامه اجازه میدهد گزارشات تماس رایانهٔ لوحی شما، از جمله دادههایی درمورد تماسهای ورودی و خروجی را تغییر دهد. برنامههای مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"به برنامه اجازه میدهد گزارشات تماس تلویزیون شما، از جمله دادههایی درمورد تماسهای ورودی و خروجی را تغییر دهد. برنامههای مخرب شاید از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"به برنامه اجازه میدهد گزارشات تماس تلفنی شما، از جمله دادههایی درمورد تماسهای ورودی و خروجی را تغییر دهد. برنامههای مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"خواندن کارت تماس شما"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"به برنامه اجازه میدهد اطلاعات نمایه شخصی ذخیره شده در دستگاه شما، مانند نام و اطلاعات تماس شما را بخواند. یعنی برنامه میتواند شما را شناسایی کند و ممکن است اطلاعات نمایهٔ شما را به دیگران ارسال کند."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"اصلاح کارت تماس شما"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"به برنامه اجازه میدهد تا اطلاعات نمایه شخصی ذخیره شده در دستگاه شما، مانند نام و اطلاعات تماس شما را تغییر دهد یا اضافه کند. یعنی برنامه میتواند شما را شناسایی کند و ممکن است اطلاعات نمایهٔ شما را برای دیگران ارسال کند."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"حسگرهای بدن (مانند پایشگرهای ضربان قلب)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"به برنامه امکان میدهد به اطلاعات حسگرهایی که بر شرایط فیزیکی شما مانند ضربان قلبتان، نظارت دارند، دسترسی داشته باشد."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"خواندن جریان اجتماعی شما"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"به برنامه اجازه میدهد به بهروزرسانیهای اجتماعی از طرف شما و دوستان شما دسترسی پیدا کرده و آنها را همگامسازی کند. دقت کنید که هنگام اشتراکگذاری -- این ویژگی به برنامه اجازه میدهد ارتباطات بین شما و دوستان شما را در شبکههای اجتماعی، صرفنظر از محرمانه بودن آنها بخواند. توجه: این مجوز ممکن است در همه شبکههای اجتماعی اجرا نشود."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"نوشتن در جریان اجتماعی شما"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"به برنامه اجازه میدهد بهروزرسانیهای اجتماعی از طرف دوستان شما را نمایش دهد. دقت کنید هنگام اشتراکگذاری اطلاعات -- این ویژگی به برنامه اجازه میدهد پیامهایی را که به نظر میرسد از طرف یکی از دوستان شما باشد ایجاد کند. توجه: این مجوز در همه شبکههای اجتماعی قابل اجرا نیست."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"خواندن رویدادهای تقویم به همراه اطلاعات محرمانه"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"به برنامه امکان میدهد همه رویدادهای تقویم ذخیره شده در رایانهٔ لوحی شما را بخواند، از جمله رویدادهای دوستان یا همکاران. این ممکن است به برنامه امکان دهد دادههای تقویم شما را صرفنظر از محرمانه یا حساس بودن آنها به اشتراک گذاشته یا ذخیره کند."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"به برنامه اجازه میدهد تا همه رویدادهای تقویم ذخیرهشده روی تلویزیون از جمله رویدادهای دوستان یا همکاران را بخواند. شاید به برنامه اجازه دهد تا اطلاعات تقویم را صرفنظر از محرمانه بودن یا حساسیت، به اشتراک بگذارد یا ذخیره کند."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"به یک برنامه اجازه میدهد تنظیمات همگامسازی را برای یک حساب اصلاح کند. بهعنوان مثال، از این ویژگی میتوان برای فعال کردن همگامسازی برنامه «افراد» با یک حساب استفاده کرد."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"خواندن اطلاعات آماری همگامسازی"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"به یک برنامه اجازه میدهد وضعیت همگامسازی یک حساب را بخواند، از جمله سابقه رویدادهای همگامسازی و میزان دادههای همگامسازی شده."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"خواندن واژههایی که به فرهنگ لغت اضافه کردید"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"به برنامه اجازه میدهد همه کلمه، نام و عباراتی را که کاربر در فرهنگ لغت خود ذخیره کرده است بخواند."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"افزودن کلمات به فرهنگ لغت تعریف شده توسط کاربر"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"به برنامه اجازه میدهد تا کلمات جدید را در فهرست کاربر بنویسد."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"خواندن محتویات حافظهٔ USB شما"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"خواندن محتویات کارت SD شما"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"به برنامه اجازه میدهد محتواهای فضای ذخیره USB را بخواند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 295028e..1e19ea6 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Sijainti"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"käyttää laitteen sijaintia"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosiaaliset tietosi"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktiesi ja internet-kontaktiesi tietojen käyttöoikeus."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenteri"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"käyttää kalenteria"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Tekstiviestit"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"lähettää ja tarkastella tekstiviestejä"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Tallennustila"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"käyttää laitteellesi tallennettuja valokuvia, mediatiedostoja ja muita tiedostoja"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Käyttäjän sanakirja"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lue tai kirjoita sanoja käyttäjän sanakirjaan."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Kirjanmerkit ja historia"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Kirjanmerkkien ja selaimen historian käyttöoikeus."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"tallentaa ääntä"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ottaa kuvia ja videoita"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Puhelin"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"soittaa ja hallinnoida puheluita"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Anturit"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"käyttää tietoja kehostasi ja liikuntaharjoituksistasi"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kehon anturit"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"käyttää anturitietoja elintoiminnoistasi"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Noutaa ikkunan sisältöä"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkistaa käyttämäsi ikkunan sisältö."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ottaa kosketuksella tutkiminen käyttöön"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Antaa sovelluksen muokata tablet-laitteesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Antaa sovelluksen muokata television puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Antaa sovelluksen muokata puhelimesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lue omia yhteystietoja"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Antaa sovelluksen lukea laitteelle tallennettuja henkilökohtaisia tietoja, kuten nimen ja yhteystietoja. Sovellus voi tunnistaa sinut ja lähettää profiilitietojasi muille."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"muokkaa omia yhteystietoja"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Antaa sovelluksen muuttaa laitteelle tallennettuja henkilökohtaisia tietoja, kuten nimeä ja yhteystietoja, tai lisätä niitä. Sovellus voi tunnistaa sinut ja lähettää profiilitietojasi muille."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kehon anturit (kuten sykemittarit)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Antaa sovelluksen käyttää kehosi tilaa seuraavien anturien tietoja, esimerkiksi sykettä."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lue sosiaalista streamia"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Antaa sovelluksen käyttää ja synkronoida sinun tai kavereidesi päivityksiä sosiaalisista palveluista. Mieti tarkkaan ennen tietojen jakamista: tämän luvan saaneet sovellukset voivat lukea sinun ja kavereidesi välisiä viestejä sosiaalisissa verkkopalveluissa huolimatta viestien arkaluonteisuudesta. Huom: tätä lupaa ei saa ottaa käyttöön kaikissa sosiaalisissa verkkopalveluissa."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"kirjoita sosiaaliseen streamiin"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Antaa sovelluksen näyttää kavereidesi päivityksiä sosiaalisista palveluista. Mieti tarkkaan ennen tietojen jakamista: tämän luvan saaneet sovellukset voivat luoda viestejä, jotka vaikuttavat kavereidesi lähettämiltä. Huom: tätä lupaa ei saa ottaa käyttöön kaikissa sosiaalisissa verkkopalveluissa."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lue kalenteritapahtumia ja luottamuksellisia tietoja"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Antaa sovelluksen lukea tablet-laitteelle tallennettuja kalenteritapahtumia, myös kavereiden tai työkavereiden tapahtumia. Sovellus voi jakaa tai tallentaa kalenteritietojasi niiden arkaluonteisuudesta huolimatta."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Antaa sovelluksen lukea kaikkia televisioon tallennettuja kalenteritapahtumia, myös kavereiden ja työkavereiden tapahtumia. Sovellus voi jakaa tai tallentaa kalenteritietoja niiden arkaluonteisuudesta huolimatta."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Antaa sovelluksen muokata tilin synkronointiasetuksia. Sovellus voi esimerkiksi ottaa Ihmiset-sovelluksen synkronoinnin käyttöön tilissä."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lue synkronointitilastoja"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Antaa sovelluksen lukea tilien synkronoinnin tilan sekä synkronoitujen tapahtumien historian ja kuinka paljon tietoja on synkronoitu."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lue sanakirjaan lisättyjä termejä"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Antaa sovelluksen lukea sanoja, nimiä tai ilmauksia, joita käyttäjä on voinut tallentaa käyttäjän sanakirjaan."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"lisää sanoja käyttäjän sanakirjaan"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Antaa sovelluksen kirjoittaa uusia sanoja käyttäjän sanakirjaan."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lue USB-tallennustilan sis."</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lue SD-kortin sisältöä"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Antaa sovelluksen lukea USB-tallennuslaitteen sisällön."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3f4f64e..3ae8ba9 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localisation"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accéder à la position de cet appareil"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vos données sur les réseaux sociaux"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accès direct aux informations sur vos contacts et vos amis sur les réseaux sociaux"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Messagerie texte"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"envoyer et afficher des messages texte"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accéder à des photos, à des contenus multimédias et à des fichiers sur votre appareil"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dctionnaire personnel"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lire ou écrire des mots dans le dictionnaire personnel."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoris et historique"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accès direct aux favoris et à l\'historique du navigateur"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et filmer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"faire et gérer des appels téléphoniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accéder à de l\'information relative à vos signes vitaux et à votre activité physique"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs sur vos signes vitaux"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permet à l\'application de modifier le journal d\'appels de votre téléviseur, y compris les données sur les appels entrants et sortants. Des applications malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lire votre fiche de contact"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permet à l\'application d\'accéder aux données de profil enregistrées sur votre appareil, comme votre nom et vos coordonnées. L\'application peut alors vous identifier et envoyer les données de votre profil à des tiers."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modifier votre fiche de contact"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet à l\'application de modifier les données de profil enregistrées sur votre appareil, telles que votre nom et vos coordonnées, ou d\'en ajouter. Elle peut alors vous identifier et envoyer vos données de profil à des tiers."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"capteurs corporels (tels que les moniteurs de fréquence cardiaque)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet à l\'application d\'accéder aux données des capteurs qui surveillent votre condition physique, comme votre rythme cardiaque."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire les flux de réseaux sociaux"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet à l\'application d\'accéder à vos mises à jour sur les réseaux sociaux, ainsi qu\'à celles de vos amis, et de les synchroniser. Soyez prudent lorsque vous partagez de l\'information. Cette autorisation permet à l\'application de lire les communications entre vous et vos amis sur les réseaux sociaux, indépendamment de leur caractère confidentiel. Remarque : Il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"modifier vos flux de réseaux sociaux"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permet à l\'application d\'afficher les mises à jour de vos amis sur les réseaux sociaux. Soyez prudent lorsque vous partagez de l\'information. Cette autorisation permet à l\'application de générer des messages qui peuvent sembler provenir d\'un ami. Remarque : Il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"consulter les événements d\'agenda ainsi que les données confidentielles qu\'ils contiennent"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permet à l\'application de lire tous les événements d\'agenda stockés sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre de partager ou d\'enregistrer vos données d\'agenda, indépendamment de leur caractère confidentiel ou sensible."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permet à l\'application de lire tous les événements du calendrier stockés sur votre téléviseur, y compris ceux de vos amis ou collègues. Cela peut permettre à l\'application de partager ou d\'enregistrer vos données de calendrier, indépendamment de la confidentialité ou de la sensibilité."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lire les statistiques de synchronisation"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"voir les termes ajoutés au dictionnaire personnel"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permet à l\'application d\'accéder aux mots, noms et expressions que l\'utilisateur a pu enregistrer dans son dictionnaire personnel."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ajouter des mots au dictionnaire personnel"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet à l\'application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lire le contenu du stockage USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lire le contenu de la carte SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permet à l\'application de lire le contenu de votre périphérique de stockage USB."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index bac4417..f4e19fb 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Position"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accéder à la position de cet appareil"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vos informations sur les réseaux sociaux"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accès direct aux informations sur vos contacts et vos amis sur les réseaux sociaux"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"envoyer et consulter des SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accéder à des photos, à des contenus multimédias et à des fichiers sur votre appareil"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dictionnaire personnel"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Consulter et ajouter des mots dans le dictionnaire personnel"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoris et historique"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accès direct aux favoris et à l\'historique du navigateur"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et enregistrer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"effectuer et gérer des appels téléphoniques"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accéder à des informations relatives à vos signes vitaux et à votre activité physique"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs relatives à vos signes vitaux"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -317,7 +311,7 @@
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permet à l\'application d\'envoyer des diffusions ancrées, qui persistent au terme de la diffusion. L\'utilisation excessive de cette fonctionnalité, qui nécessite beaucoup de mémoire, peut ralentir le téléviseur ou nuire à sa stabilité."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
- <string name="permlab_readContacts" msgid="8348481131899886131">"voir les contacts"</string>
+ <string name="permlab_readContacts" msgid="8348481131899886131">"Voir les contacts"</string>
<string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Permet à l\'application de lire les données relatives à vos contacts sur le téléviseur, y compris la fréquence de vos appels, de vos e-mails et de toute autre communication avec ces personnes. Cette autorisation permet aux applications d\'enregistrer les données relatives à vos contacts. Les applications malveillantes sont susceptibles de partager ces données à votre insu."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permet à l\'application de lire le journal d\'appels du téléviseur, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"voir votre fiche de contact"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permet à l\'application d\'accéder aux informations de profil stockées sur votre appareil, telles que votre nom et vos coordonnées. L\'application peut alors vous identifier et envoyer vos informations de profil à des tiers."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modifier votre fiche de contact"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet à l\'application de modifier les informations de profil stockées sur votre appareil, telles que votre nom et vos coordonnées, ou d\'en ajouter. Elle peut alors vous identifier et envoyer vos informations de profil à des tiers."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"capteurs corporels (tels que les cardiofréquencemètres)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet à l\'application d\'accéder aux données des capteurs qui contrôlent votre condition physique, comme votre rythme cardiaque."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire votre flux de réseau social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet à l\'application d\'accéder à vos mises à jour sur les réseaux sociaux, ainsi qu\'à celles de vos amis, et de les synchroniser. Soyez prudent lorsque vous partagez des informations. Cette autorisation permet à l\'application de lire les communications entre vous et vos amis sur les réseaux sociaux, indépendamment de leur caractère confidentiel. Remarque : il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"écrire sur votre flux social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permet à l\'application d\'afficher les mises à jour de vos amis sur les réseaux sociaux. Soyez prudent lorsque vous partagez des informations. Cette autorisation permet à l\'application de générer des messages qui peuvent sembler provenir d\'un ami. Remarque : il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"consulter les événements d\'agenda ainsi que les informations confidentielles"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permet à l\'application de lire tous les événements d\'agenda stockés sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre de partager ou d\'enregistrer vos données d\'agenda, indépendamment de leur caractère confidentiel ou sensible."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permet à l\'application de lire tous les événements d\'agenda stockés sur le téléviseur, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut permettre à l\'application de partager ou d\'enregistrer vos données d\'agenda, indépendamment de leur niveau de confidentialité."</string>
@@ -371,7 +357,7 @@
<string name="permdesc_flashlight" msgid="6522284794568368310">"Permet à l\'application de contrôler la lampe de poche."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"appeler directement les numéros de téléphone"</string>
<string name="permdesc_callPhone" msgid="3740797576113760827">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Les applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
- <string name="permlab_readPhoneState" msgid="9178228524507610486">"voir l\'état et l\'identité du téléphone"</string>
+ <string name="permlab_readPhoneState" msgid="9178228524507610486">"Voir l\'état et l\'identité du téléphone"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"empêcher la tablette de passer en mode veille"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"empêcher l\'activation du mode veille sur le téléviseur"</string>
@@ -427,7 +413,7 @@
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"contrôler la communication en champ proche"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permet à l\'application de communiquer avec des tags, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string>
- <string name="permlab_disableKeyguard" msgid="3598496301486439258">"désactiver le verrouillage de l\'écran"</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Désactiver le verrouillage de l\'écran"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité via mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gérer le matériel d\'empreintes digitales"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Autoriser l\'application à invoquer des méthodes pour ajouter et supprimer des modèles d\'empreintes digitales"</string>
@@ -455,15 +441,11 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Lecture des statistiques de synchronisation"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"voir les termes ajoutés au dictionnaire"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permet à l\'application d\'accéder aux mots, noms et expressions que l\'utilisateur a pu enregistrer dans son dictionnaire personnel."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ajouter des mots au dictionnaire personnel"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet à l\'application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"voir le contenu de la mémoire USB"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"Voir le contenu de la mémoire USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"voir le contenu de la carte SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permettre de lire contenu de la mémoire de stockage USB"</string>
<string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permettre à l\'application de lire le contenu de la carte SD"</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifier ou supprimer le contenu de la mémoire USB"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"Modifier ou supprimer le contenu de la mémoire USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifier ou supprimer le contenu de la carte SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permet à l\'application de modifier le contenu de la mémoire de stockage USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string>
@@ -1033,7 +1015,7 @@
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOUVEAU"</font>" :"</string>
<string name="perms_description_app" msgid="5139836143293299417">"Fourni par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
- <string name="perm_costs_money" msgid="4902470324142151116">"cela peut engendrer des frais"</string>
+ <string name="perm_costs_money" msgid="4902470324142151116">"Cela peut engendrer des frais"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Mémoire de stockage de masse USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Connecté par USB"</string>
<string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre appareil Android, ou inversement."</string>
@@ -1356,7 +1338,7 @@
<string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
<string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="user_switching_message" msgid="2871009331809089783">"Passage à (<xliff:g id="NAME">%1$s</xliff:g>) en cours…"</string>
+ <string name="user_switching_message" msgid="2871009331809089783">"Chargement du profil de <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
<string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
<string name="error_message_change_not_allowed" msgid="1347282344200417578">"Votre administrateur n\'autorise pas cette modification."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index c2dcd0c..f2db033 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localización"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acceso á localización deste dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"A túa información social"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceso directo a información acerca dos teus contactos e as conexións sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder ao teu calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"envía e consulta mensaxes de SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Almacenamento"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accede a fotos, contido multimedia e ficheiros no teu dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionario de usuario"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escribir palabras no dicionario de usuario."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoritos e historial"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceso directo aos favoritos e ao historial do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"facer e xestionar chamadas telefónicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accede a información sobre as túas constantes vitais e a actividade física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accede aos datos do sensor sobre as túas constantes vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar contido da ventá"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona o contido dunha ventá coa que estás interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar a exploración táctil"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite á aplicación modificar o rexistro de chamadas do tablet, incluídos os datos acerca de chamadas entrantes e saíntes. É posible que aplicacións maliciosas utilicen esta acción para borrar ou modificar o teu rexistro de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite que a aplicación modifique o rexistro de chamadas da televisión, incluídos os datos sobre chamadas entrantes e saíntes. As aplicacións maliciosas poden utilizar este permiso para borrar ou modificar o rexistro de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite á aplicación modificar o rexistro de chamadas do teléfono, incluídos os datos acerca de chamadas entrantes e saíntes. É posible que aplicacións maliciosas utilicen esta acción para borrar ou modificar o teu rexistro de chamadas."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ler a túa tarxeta de contacto"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite á aplicación ler información do perfil persoal almacenada no teu dispositivo, como o teu nome e información de contacto. Isto significa que a aplicación pode identificarte e enviar a información do teu perfil a outras persoas."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modificar tarxeta de contacto"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite á aplicación cambiar ou engadir á información do perfil persoal almacenada no teu dispositivo, como o teu nome e información de contacto. Isto significa que a aplicación pode identificarte e enviar a información do teu perfil a outros usuarios."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensores de corpo (como monitores de ritmo cardíaco)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que a aplicación acceda aos datos dos sensores que controlan o teu estado físico, como o ritmo cardíaco."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler a túa actividade social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite á aplicación acceder ás túas actualizacións nas redes sociais, e sincronizalas, e ás dos teus amigos. Ten coidado ao compartir información (esta acción permite á aplicación ler comunicacións entre ti e os teus amigos efectuadas a través das redes sociais, independentemente da súa confidencialidade). Nota: É posible que este permiso non se execute en todas as redes sociais."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escribir na túa actividade social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite á aplicación mostrar actualizacións de redes sociais dos teus amigos. Ten coidado ao compartir información, esta acción permite á aplicación xerar mensaxes que parecen proceder dun amigo. Nota: É posible que este permiso non se execute en todas as redes sociais."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ler os eventos do calendario e a información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite á aplicación ler todos os eventos do calendario que están almacenados no tablet, incluídos os pertencentes aos teus amigos ou compañeiros de traballo. É posible que esta acción permita á aplicación compartir ou gardar os datos do teu calendario, independentemente da confidencialidade."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite que a aplicación consulte todos os eventos do calendario almacenados na televisión, incluídos os de amigos e compañeiros de traballo. A aplicación pode utilizar este permiso para compartir ou gardar datos do calendario, sen ter en conta o nivel de privacidade ou confidencialidade."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite a unha aplicación modificar a configuración de sincronización dunha conta. Por exemplo, esta acción pode utilizarse para activar a sincronización da aplicación Contactos cunha conta."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ler as estatísticas de sincronización"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite a unha aplicación ler as estatísticas de sincronización dunha conta, incluído o historial de eventos de sincronización e a cantidade de datos sincronizados."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ler os termos engadidos ao dicionario"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite á aplicación ler todas as palabras, nomes e frases gardados polo usuario no dicionario do usuario."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"engadir palabras ao dicionario definido polo usuario"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite á aplicación escribir palabras novas no dicionario do usuario."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ler contidos do teu USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ler os contidos da túa tarxeta SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite á aplicación ler o contido do teu almacenamento USB."</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 8a75dbe..78de77e 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરો"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"તમારી સામાજિક માહિતી"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"તમારા સંપર્કો અને સામાજિક કનેક્શન્સ વિશેની માહિતીની સીધી ઍક્સેસ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"કૅલેન્ડર"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"તમારા કેલેન્ડરને ઍક્સેસ કરો"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS સંદેશા મોકલો અને જુઓ"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"સ્ટોરેજ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"તમારા ઉપકરણ પર ફોટા, મીડિયા અને ફાઇલો ઍક્સેસ કરો"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"વપરાશકર્તા શબ્દકોશ"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"વપરાશકર્તા શબ્દકોશમાં શબ્દો વાંચો અથવા લખો."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"બુકમાર્ક્સ અને ઇતિહાસ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"બુકમાર્ક્સ અને બ્રાઉઝર ઇતિહાસની સીધી ઍક્સેસ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"માઇક્રોફોન"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ઑડિઓ રેકોર્ડ કરો"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"કૅમેરો"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લો અને વિડિઓ રેકોર્ડ કરો"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ફોન"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો તથા સંચાલિત કરો"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"સેન્સર્સ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"તમારા મહત્વપૂર્ણ ચિહ્નો અને શારીરિક પ્રવૃત્તિ વિશેની માહિતી ઍક્સેસ કરો"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"બોડી સેન્સર્સ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો સામગ્રી પુનર્પ્રાપ્ત કરો"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"તમે જેની સાથે ક્રિયાપ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોની સામગ્રીની તપાસ કરો."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ટચ કરીને અન્વેષણ કરો સક્ષમ કરો"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા ટેબ્લેટના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ એપ્લિકેશન્સ આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા TV ના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ એપ્લિકેશન્સ આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા ફોનના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ એપ્લિકેશન્સ આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"તમારું પોતાનું સંપર્ક કાર્ડ વાંચો"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"એપ્લિકેશનને તમારા નામ અને સંપર્ક માહિતી જેવી તમારા ઉપકરણ પર સંગ્રહિત વ્યક્તિગત પ્રોફાઇલ માહિતીને વાંચવાની મંજૂરી આપે છે. આનો અર્થ છે કે એપ્લિકેશન તમને ઓળખી શકે છે અને અન્ય લોકોને તમારી પ્રોફાઇલ માહિતી મોકલી શકે છે."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"તમારું પોતાનું સંપર્ક કાર્ડ સંશોધિત કરો"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"એપ્લિકેશનને તમારા નામ અને સંપર્ક માહિતી જેવી તમારા ઉપકરણ પર સંગ્રહિત વ્યક્તિગત પ્રોફાઇલ માહિતીને બદલા અથવા ઉમેરવાની મંજૂરી આપે છે. આનો અર્થ છે કે એપ્લિકેશન તમને ઓળખી શકે છે અને અન્ય લોકોને તમારી પ્રોફાઇલ માહિતી મોકલી શકે છે."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"બૉડી સેન્સર્સ (જેમ કે હાર્ટ રેટ મૉનિટર્સ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"એપ્લિકેશનને તમારી હૃદય ગતિ જેવી તમારી શારીરિક સ્થિતિને મૉનિટર કરતાં સેન્સર્સથી ડેટા ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"તમારી સામાજિક સ્ટ્રીમ વાંચો"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"એપ્લિકેશનને તમારા અને તમારા મિત્રોના સામાજિક અપડેટ્સ ઍક્સેસ કરવા અને સમન્વયિત કરવાની મંજૂરી આપે છે. માહિતી શેર કરતી વખતે સાવચેત રહો -- આ એપ્લિકેશનને સામાજિક નેટવર્ક્સ પર તમારી અને તમારા મિત્રોની વચ્ચેના સંચારને વાંચવાની મંજૂરી આપે છે, પછી ભલેને ગોપનીયતા કોઈપણ હોય. નોંધ: આ પરવાનગી બધા સામાજિક નેટવર્ક્સ પર લાગુ કરી શકાશે નહીં."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"તમારા સામાજિક સ્ટ્રીમ પર લખો"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"એપ્લિકેશનને તમારા મિત્રોના સામાજિક અપડેટ્સ પ્રદર્શિત કરવાની મંજૂરી આપે છે. માહિતી શેર કરતી વખતે સાવચેત રહો -- આ એપ્લિકેશનને મિત્ર તરફથી આવતું દેખાઈ શકે તેવા સંદેશા નિર્મિત કરવાની મંજૂરી આપે છે. નોંધ: આ પરવાનગી બધા સામાજિક નેટવર્ક્સ પર લાગુ કરી શકાશે નહીં."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"કૅલેન્ડર ઇવેન્ટ્સ વત્તા ગોપનીયતા માહિતી વાંચો"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કૅલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કૅલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"એપ્લિકેશનને એકાઉન્ટ માટે સમન્વયન સેટિંગ્સ સંશોધિત કરવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આનો ઉપયોગ એકાઉન્ટ સાથે લોકો એપ્લિકેશનના સમન્વયનને સક્ષમ કરવા માટે થઈ શકે છે."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"સમન્વયન આંકડા વાંચો"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"એપ્લિકેશનને સમન્વયન ઇવેન્ટ્સનો ઇતિહાસ અને કેટલો ડેટા સમન્વયિત થયો છે તે સહિત કોઈ એકાઉન્ટ માટેનાં સમન્વયન આંકડા વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"તમે શબ્દકોશમાં ઉમેરેલ શબ્દો વાંચો"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"એપ્લિકેશનને વપરાશકર્તાએ વપરાશકર્તા શબ્દકોશમાં સંગ્રહિત કર્યા હોઈ શકે છે તે તમામ શબ્દો, નામો અને શબ્દસમૂહોને વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"વપરાશકર્તા દ્વારા વ્યાખ્યાયિત શબ્દકોશમાં શબ્દો ઉમેરો"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"એપ્લિકેશનને વપરાશકર્તા શબ્દકોશ પર નવા શબ્દો લખવાની મંજૂરી આપે છે."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"તમારા USB સંગ્રહની સામગ્રીઓ વાંચો"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"તમારા SD કાર્ડની સામગ્રીઓ વાંચો"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"એપ્લિકેશનને તમારા USB સંગ્રહની સામગ્રીઓ વાંચવાની મંજૂરી આપે છે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 90ac653..79f376b 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"इस डिवाइस के स्थान को ऐक्सेस करें"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"आपकी सामाजिक जानकारी"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"अपने संपर्कों और सामाजिक कनेक्शन के बारे में जानकारी पर सीधी पहुंच."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"कैलेंडर"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"अपने कैलेंडर को ऐक्सेस करें"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS संदेश भेजें और देखें"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"मेमोरी"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"अपने डिवाइस पर मौजूद फ़ोटो, मीडिया और फ़ाइलें ऐक्सेस करें"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"उपयोगकर्ता शब्दकोश"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"उपयोगकर्ता डिक्शनरी में शब्द पढ़ें या लिखें."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्क और इतिहास"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्क और ब्राउज़र इतिहास पर सीधी पहुंच."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफ़ोन"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"कैमरा"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्र लें और वीडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फ़ोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करें और प्रबंधित करें"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"संवेदक"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"अपने महत्वपूर्ण संकेतों और शारीरिक गतिविधि के बारे में जानकारी ऐक्सेस करें"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर संवेदक"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री प्राप्त करें"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"उस विंडो की सामग्री का निरीक्षण करें जिससे आप सहभागिता कर रहे हैं."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श द्वारा एक्सप्लोर करें को चालू करें"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ऐप को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टैबलेट के कॉल लॉग में बदलाव करने देती है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए उसका उपयोग कर सकते हैं."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"स्वयं का संपर्क कार्ड पढ़ें"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ऐप्स को आपके डिवाइस में संग्रहीत व्यक्तिगत प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी, पढ़ने देता है. इसका अर्थ है कि ऐप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"स्वयं का संपर्क कार्ड बदलें"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ऐप्स को आपके डिवाइस में संग्रहीत निजी प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी को बदलने या उसमें कुछ जोड़ने देता है. इसका अर्थ है कि ऐप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"बॉडी सेंसर (जैसे हृदय गति मॉनीटर)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्सेस करने देती है."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"अपनी सामाजिक स्ट्रीम पढ़ें"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"एप को आपके और आपके मित्रों की नई सामाजिक जानकारी तक पहुंचने और उन्हें समन्वयित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे गोपनीयता पर ध्यान दिए बिना, एप सामाजिक नेटवर्क पर आपके और आपके मित्रों के बीच संचारों को पढ़ सकता है. ध्यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"सामाजिक स्ट्रीम में लिखें"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"एप को आपके मित्रों की नई सामाजिक जानकारी प्रदर्शित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे ऐप्स ऐसे संदेश बना सकता है जो किसी मित्र की ओर से आते दिखाई देते हैं. ध्यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर ईवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ऐप्स को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके टेबलेट पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, ऐप्स आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ऐप को, मित्रों और सहकर्मियों के कैलेंडर ईवेंट सहित, आपके टीवी पर संग्रहीत सभी कैलेंडर ईवेंट पढ़ने देती है. इससे ऐप को गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, आपका कैलेडर डेटा साझा करने या सहेजने की अनुमति मिल जाती है."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ऐप्स को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग ऐप्स का समन्वयन किसी खाते से सक्षम करने में हो सकता है."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स को किसी खाते के समन्वयन आंकड़े, साथ ही समन्वयित ईवेंट का इतिहास और समन्वयित डेटा की मात्रा पढ़ने देता है."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"शब्दकोश में आपके द्वारा जोड़े गए शब्दों को पढ़ें"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ऐप्स को ऐसे सभी शब्दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता शब्दकोश में संग्रहीत किए गए हों."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"उपयोगकर्ता द्वारा परिभाषित शब्दकोश में शब्द जोड़ें"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ऐप्स को उपयोगकर्ता शब्दकोश में नए शब्द लिखने देता है."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"अपने USB मेमोरी की सामग्री पढ़ें"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"अपने SD कार्ड की सामग्री पढ़ें"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"एप्लिकेशन को आपके USB मेमोरी की सामग्री पढ़ने की अनुमति देता है."</string>
@@ -1272,7 +1253,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..3b7e048 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,32 +225,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"pristupiti lokaciji ovog uređaja"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informacije o vašoj društvenoj aktivnosti"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Izravan pristup informacijama o kontaktima i društvenim vezama."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupati kalendaru"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"slati i pregledavati SMS poruke"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za pohranu"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"pristupiti fotografijama, medijima i datotekama na vašem uređaju"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Korisnički rječnik"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čitanje ili pisanje riječi u korisničkom rječniku."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Oznake i povijest"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Izravan pristup oznakama i povijest preglednika."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"snimati zvuk"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparat"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"snimati fotografije i videozapise"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"uspostavljati telefonske pozive i upravljati njima"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"pristupiti informacijama o vašim vitalnim znakovima i fizičkoj aktivnosti"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupiti podacima senzora o vašim vitalnim znakovima"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dohvaćati sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji upotrebljavate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključiti značajku Istraži dodirom"</string>
@@ -334,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg tabletnog računala zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Aplikaciji omogućuje izmjenu zapisnika poziva vašeg televizora zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg zapisnika poziva."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg telefona zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"čitanje vaše kontaktne kartice"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Aplikaciji omogućuje čitanje osobnih podataka profila pohranjenih na uređaju, kao što su vaše ime ili kontaktni podaci. To znači da vas aplikacija može identificirati i slati informacije s vašeg profila drugima."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"izmjena vaše kontaktne kartice"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Aplikaciji omogućuje promjenu ili dodavanje osobnih podataka profila pohranjenih na uređaju, kao što su vaše ime i kontaktni podaci. To znači da vas aplikacija može identificirati i slati informacije s vašeg profila drugima."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"senzori tjelesnih funkcija (npr. monitori otkucaja srca)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Omogućuje aplikaciji pristup podacima sa senzora koji nadziru vaše fizičko stanje, na primjer, broj otkucaja srca."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čitanje društvenog streama"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Aplikaciji omogućuje pristup vašim ažuriranjima na društvenim mrežama i ažuriranjima vaših prijatelja, kao i sinkronizaciju tih ažuriranja. Budite oprezni kad dijelite informacije – to aplikaciji omogućuje čitanje poruka između vas i vaših prijatelja na društvenim mrežama, neovisno o povjerljivosti. Napomena: ta se dozvola možda ne primjenjuje na svim društvenim mrežama."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pisanje društvenog streama"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Aplikaciji omogućuje prikazivanje ažuriranja vaših prijatelja na društvenim mrežama. Budite oprezni kad dijelite informacije – to aplikaciji omogućuje stvaranje poruka koje mogu izgledati kao da dolaze od prijatelja. Napomena: ta se dozvola možda ne primjenjuje na svim društvenim mrežama."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čitajte kalendarske događaje i povjerljive informacije"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Aplikaciji omogućuje čitanje svih događaja u kalendaru pohranjenih na vašem tabletnom računalu, uključujući one od vaših prijatelja ili suradnika. To aplikaciji može omogućiti dijeljenje ili spremanje vaših podataka kalendara, neovisno o povjerljivosti ili osjetljivosti."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Aplikaciji omogućuje čitanje svih kalendarskih događaja pohranjenih na televizoru, uključujući događaje koji pripadaju vašim prijateljima i suradnicima. Aplikacija tako može dijeliti ili spremati vaše kalendarske podatke, bez obzira na povjerljivost i osjetljivost."</string>
@@ -456,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Aplikaciji omogućuje izmjenu postavki sinkronizacije za račun. Na primjer, to se može upotrijebiti za omogućavanje sinkronizacije aplikacije Osobe s računom."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"čitanje statistike o sinkronizaciji"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Aplikaciji omogućuje čitanje statistika sinkronizacije za račun, uključujući povijest sinkronizacije te količinu sinkroniziranih podataka."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"čitanje pojmova koje ste dodali u rječnik"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Aplikaciji omogućuje čitanje svih riječi, imena i fraza koje je korisnik pohranio u korisničkom rječniku."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"dodavanje riječi u rječnik koji je izradio korisnik"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Aplikaciji omogućuje pisanje novih riječi u korisnički rječnik."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"čitanje sadržaja USB pohrane"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čitanje sadržaja SD kartice"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Aplikaciji omogućuje čitanje sadržaja vaše USB pohrane."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 70f006e..9a4bd5a 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Helyadatok"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"hozzáférés az eszköz földrajzi helyéhez"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Az Ön közösségi adatai"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Közvetlen hozzáférés a névjegyekre és közösségi kapcsolatokra vonatkozó információkhoz"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Naptár"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"hozzáférés a naptárhoz"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS-ek küldése és megtekintése"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Tárhely"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"az eszközön lévő fotók, médiatartalmak és fájlok elérése"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Felhasználói szótár"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Szavak olvasása vagy írása a felhasználói szótárban."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Könyvjelzők és előzmények"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Közvetlen hozzáférés a könyvjelzőkhöz és a böngészési előzményekhez"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"hanganyag rögzítése"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fényképezőgép"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotók és videók készítése"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonhívások kezdeményezése és kezelése"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Érzékelők"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"életjelekkel és fizikai tevékenységgel kapcsolatos információk elérése"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Testérzékelők"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"az érzékelők által mért, életjelekkel kapcsolatos adatok elérése"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ablaktartalom lekérdezése"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"A használt ablak tartalmának vizsgálata."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Felfedezés érintéssel bekapcsolása"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lehetővé teszi, hogy az alkalmazás módosítsa a táblagép híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Lehetővé teszi, hogy az alkalmazás módosítsa a tévé hívásnaplóját, így például a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt hívásnaplója törlésére vagy módosítására használhatják."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lehetővé teszi, hogy az alkalmazás módosítsa a telefon híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"saját névjegykártya olvasása"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Lehetővé teszi az alkalmazás számára, hogy hozzáférést biztosítson az eszközön tárolt személyes profiladatokhoz, például a névhez és az elérhetőségekhez. Ez azt jelenti, hogy az alkalmazás azonosíthatja Önt, és elküldheti másoknak profiladatait."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"saját névjegykártya módosítása"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lehetővé teszi az alkalmazás számára az eszközön tárolt személyes profiladatok, például a név és az elérhetőségek módosítását vagy hozzáadását. Ez azt jelenti, hogy az alkalmazás azonosíthatja Önt, és elküldheti másoknak profiladatait."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"testérzékelők (pl. pulzusmérő)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Engedélyezi az alkalmazásnak, hogy hozzáférjen az Ön fizikai állapotát – például a pulzusszámát – figyelő érzékelők adataihoz."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"közösségi adatfolyam olvasása"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az Ön és ismerősei közösségi oldalakon szereplő frissítéseihez. Legyen elővigyázatos, amikor információt tesz közzé -- így az alkalmazás hozzáférhet az ismerőseivel a közösségi hálózatokon folytatott magánbeszélgetésekhez, a tartalom titkos jellegétől függetlenül. Megjegyzés: előfordulhat, hogy ez nincs minden közösségi hálózaton engedélyezve."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"írás a közösség adatfolyamra"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Lehetővé teszi az alkalmazás számára, hogy megjelenítse ismerősei közösségi oldalakon szereplő frissítéseit. Legyen elővigyázatos, amikor információt tesz közzé -- így az alkalmazás olyan üzeneteket hozhat létre, amelyek látszólag egy ismerőstől érkeztek. Megjegyzés: előfordulhat, hogy ez nincs minden közösségi hálózaton engedélyezve."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"naptári események és bizalmas információk beolvasása"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Lehetővé teszi az alkalmazás számára a táblagépén tárolt összes naptári esemény beolvasását, beleértve az ismerősök vagy munkatársak eseményeit is. Az alkalmazás így megoszthatja vagy elmentheti az Ön naptáradatait azok titkos vagy bizalmas jellegétől függetlenül."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Lehetővé teszi az alkalmazás számára a tévéjén tárolt összes naptáresemény elolvasását, beleértve az ismerősök vagy munkatársak eseményeit is. Ezáltal az alkalmazás megoszthatja vagy mentheti az Ön naptáradatait, az adatok titkosságára vagy érzékeny jellegére való tekintet nélkül."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Lehetővé teszi az alkalmazás számára egy fiók szinkronizálási beállításainak módosítását. Például ezzel engedélyezni lehet a Személyek alkalmazás szinkronizálását egy fióknál."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"szinkronizálási statisztikák olvasása"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Lehetővé teszi az alkalmazás számára egy fiók szinkronizálási statisztikáinak a beolvasását, beleértve a szinkronizálási események előzményeit, valamint a szinkronizált adatok mennyiségét."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"szótárhoz adott kifejezések olvasása"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Lehetővé teszi az alkalmazás számára, hogy beolvassa a felhasználói szótárban tárolt összes szót, nevet és kifejezést."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"szavak hozzáadása a felhasználó által definiált szótárhoz"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Lehetővé teszi az alkalmazás számára, hogy új szavakat írjon a felhasználói szótárba."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB-tár tartalmának olvasása"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD-kártya tartalmának olvasása"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Beolvashat USB-tárakat."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 806d70a..b8e944f 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Տեղադրություն"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"օգտագործել այս սարքի տեղադրությունը"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ձեր սոցիալական տեղեկությունները"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ուղղակի մուտք ձեր կոնտակտների մասին տեղեկություններ և սոցիալական կապեր:"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"օրացույցի հասանելիություն"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Կարճ հաղորդագրություն"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ուղարկել և դիտել SMS հաղորդագրությունները"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Պահոց"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"օգտագործել լուսանկարները, մեդիա ֆայլերը և ձեր սարքում պահվող այլ ֆայլերը"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Օգտվողի բառարան"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Կարդալ կամ ավելացնել բառեր օգտվողի բառարանում:"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Էջանիշեր և պատմություն"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ուղղակի մուտք դեպի էջանիշեր և դիտարկիչի պատմություն:"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Բարձրախոս"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ձայնագրում"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Ֆոտոխցիկ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"լուսանկարում և տեսագրում"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Հեռախոս"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"հեռախոսազանգերի կատարում և կառավարում"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Սենսորներ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"օգտագործել ձեր հիմնական ֆիզիոլոգիական ցուցանիշների և ֆիզիկական գործունեության վերաբերյալ տեղեկությունները"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Մարմնի սենսորներ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"օգտագործել ձեր հիմնական ֆիզիոլոգիական ցուցանիշների վերաբերյալ սենսորի տվյալները"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Առբերել պատուհանի բովանդակությունը"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ստուգեք պատուհանի բովանդակությունը, որի հետ փոխգործակցում եք:"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Միացնել Հպման միջոցով հետազոտումը"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Թույլ է տալիս հավելվածին փոփոխել ձեր գրասալիկի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Թույլ է տալիս հավելվածին փոփոխել հեռուստացույցի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"կարդալ ձեր սեփական կոնտակտային քարտը"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքում պահված անհատական պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"փոփոխել ձեր սեփական կոնտակտային քարտը"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Թույլ է տալիս հավելվածին փոխել կամ ավելացնել ձեր սարքում պահված անհատական պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"մարմնի սենսորներ (օր.` սրտի)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Հավելվածին թույլ է տալիս մուտք ունենալ սենսորների տվյալներին, որոնք վերահսկում են ձեր ֆիզիկական վիճակը, օրինակ՝ ձեր սրտի զարկերը:"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"կարդալ ձեր սոցիալական հոսքը"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Թույլ է տալիս հավելվածին մուտք գործել և համաժամեցնել ձեր և ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին կարդալ ձեր և ձեր ընկերների միջև անձնական հաղորդագրությունները սոցիալական ցանցերում` անկախ գաղտնիությունից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"գրել ձեր սոցիալական հոսքում"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Թույլ է տալիս հավելվածին ցուցադրել ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին հաղորդագություններ ստեղծել, որոնք իբրև ստացվում են ընկերոջից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"կարդալ օրացուցային իրադարձությունները և գաղտնի տեղեկությունները"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկում պահված բոլոր օրացուցային իրադարձությունները, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին տարածել կամ պահել ձեր օրացուցային տվյալները` անկախ գաղտնիությունից կամ զգայունությունից:"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Թույլ է տալիս հավելվածին կարդալ հեռուստացույցի օրացույցում պահված բոլոր իրադարձությունները, այդ թվում նաև ընկերների կամ գործընկերների հետ կապված իրադարձությունները: Սա կարող է թույլ տալ հավելվածին համօգտագործել կամ պահել ձեր օրացույցի տվյալները՝ անկախ նրանց գաղտնիության կամ կարևորության աստիճանից:"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Թույլ է տալիս հավելվածին փոփոխել համաժամեցման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամեցումը հաշվի հետ:"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"կարդալ համաժամեցման վիճակագրությունը"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Թույլ է տալիս հավելվածին կարդալ հաշվի համաժամեցման վիճակագրությունը, այդ թվում` համաժամեցման իրադարձությունների պատմությունը և թե որքան տվյալ է համաժամեցված:"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"կարդալ պայմանները, որ ավելացրել եք բառարանում"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Թույլ է տալիս հավելվածին կարդալ բոլոր բառերը, անունները և արտահայտությունները, որոնք օգտագործողը հնարավոր է պահել է օգտվողի բառարանում:"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ավելացնել բառեր օգտվողի համար սահմանված բառարանում"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Թույլ է տալիս հավելվածին գրել նոր բառեր օգտվողի բառարանում:"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"կարդալ ձեր USB կրիչի պարունակությունը"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"կարդալ ձեր SD քարտի պարունակությունը"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Հավելվածին թույլ է տալիս կարդալ ձեր USB կրիչի պարունակությունը:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ffbf564..44bdf3e 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"mengakses lokasi perangkat ini"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informasi sosial Anda"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke informasi tentang kontak dan hubungan sosial Anda."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"mengirim dan melihat pesan SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Penyimpanan"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"mengakses foto, media, dan file di perangkat"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamus Pengguna"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Membaca atau menulis kata dalam kamus pengguna."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmark dan Riwayat"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke bookmark dan riwayat browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekam audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"mengambil gambar dan merekam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"melakukan dan mengelola panggilan telepon"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"mengakses informasi tentang tanda-tanda vital dan aktivitas fisik"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensor Tubuh"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"mengakses data sensor tentang tanda-tanda vital"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Mengambil konten jendela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Memeriksa konten jendela tempat Anda berinteraksi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Memungkinkan apl memodifikasi log panggilan tablet Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Mengizinkan aplikasi untuk memodifikasi log panggilan TV, termasuk data tentang panggilan masuk dan keluar. Aplikasi berbahaya mungkin menggunakan ini untuk menghapus atau memodifikasi log panggilan."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Memungkinkan apl memodifikasi log panggilan ponsel Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"baca kartu kontak Anda"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Memungkinkan aplikasi membaca informasi profil pribadi yang tersimpan di perangkat Anda, misalnya nama dan informasi kontak Anda. Ini artinya aplikasi dapat mengenali dan mengirim informasi profil Anda ke orang lain."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ubah kartu kontak Anda"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Memungkinkan aplikasi mengubah atau menambah informasi profil pribadi yang tersimpan di perangkat Anda, seperti nama dan informasi kontak. Ini berarti aplikasi tersebut dapat mengenali Anda dan mengirim informasi profil Anda ke orang lain."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensor tubuh (misal: monitor detak jantung)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Mengizinkan aplikasi untuk mengakses data dari sensor yang memantau kondisi fisik Anda, seperti denyut jantung."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"membaca aliran sosial Anda"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Memungkinkan aplikasi mengakses dan menyinkronkan pembaruan sosial dari Anda dan teman. Hati-hati ketika berbagi informasi -- izin ini memungkinkan aplikasi membaca komunikasi antara Anda dan teman di jejaring sosial, terlepas dari kerahasiaan. Catatan: izin ini tidak dapat diberlakukan di semua jejaring sosial."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"menulis ke aliran sosial Anda"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Memungkinkan aplikasi menampilkan pembaruan sosial dari teman Anda. Berhati-hatilah saat berbagi informasi -- izin ini memungkinkan aplikasi menghasilkan pesan yang mungkin kelihatannya berasal dari seorang teman. Catatan: izin ini tidak dapat diberlakukan di semua jejaring sosial."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalender serta informasi rahasia"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Memungkinkan aplikasi membaca semua acara kalender yang tersimpan di tablet Anda, termasuk milik teman atau rekan kerja. Izin ini memungkinkan aplikasi berbagi atau menyimpan data kalender Anda, terlepas dari kerahasiaan atau sensitivitas."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Mengizinkan aplikasi untuk membaca semua acara kalender yang disimpan di TV, termasuk milik teman atau rekan kerja. Izin ini memungkinkan aplikasi untuk membagikan atau menyimpan data kalender, meski data tersebut bersifat rahasia atau sensitif."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Memungkinkan aplikasi mengubah setelan sinkronisasi untuk sebuah akun. Misalnya, izin ini dapat digunakan untuk mengaktifkan sinkronisasi dari aplikasi Orang dengan sebuah akun."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"statistika baca sinkron"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Memungkinkan aplikasi membaca statistik sinkronisasi untuk sebuah akun, termasuk riwayat kejadian sinkronisasi dan berapa banyak data yang disinkronkan."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"baca istilah yang Anda tambahkan ke kamus"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Memungkinkan aplikasi membaca semua kata, nama, dan frasa yang mungkin disimpan oleh pengguna di kamus pengguna."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"Menambahkan kata ke kamus yang ditentukan pengguna"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Mengizinkan apl menulis kata-kata baru ke dalam kamus pengguna."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"baca konten simpanan USB Anda"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"baca konten kartu SD Anda"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Mengizinkan aplikasi membaca konten penyimpanan USB Anda."</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index cfc3ea4..8801523 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Staðsetning"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"fá aðgang að staðsetningu þessa tækis"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Samfélagsupplýsingarnar þínar"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Beinn aðgangur að upplýsingum um tengiliði og samfélagstengingar."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Dagatal"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"fá aðgang að dagatalinu þínu"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"senda og skoða SMS-skilaboð"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Geymslurými"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"fá aðgang að myndum, efni og skrám í tækinu"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Orðabók notanda"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lesa eða skrifa orð í orðabók notanda."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bókamerki og ferill"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Beinn aðgangur að bókamerkjum og vafraferli."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Hljóðnemi"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"taka upp hljóð"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Myndavél"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"taka myndir og taka upp myndskeið"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Sími"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"hringja og stjórna símtölum"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Skynjarar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"fá aðgang að upplýsingum um líkamsstarfsemi þína og hreyfingu"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"aðgangur að skynjaragögnum yfir lífsmörk þín"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Sækja innihald glugga"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kanna innihald glugga sem þú ert að nota."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Kveikja á snertikönnun"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Leyfir forriti að breyta símtalaskrá spjaldtölvunnar, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Leyfir forriti að breyta símtalaskrá sjónvarpsins, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Leyfir forriti að breyta símtalaskrá símans, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lesa tengiliðaspjaldið þitt"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Leyfir forriti að lesa persónulegar prófílupplýsingar sem vistaðar eru í tækinu, t.d. nafn og samskiptaupplýsingar. Þetta þýðir að forritið veit hver þú ert og getur sent prófílupplýsingarnar þínar til annarra."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"breyta tengiliðaspjaldinu þínu"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Leyfir forriti að breyta eða bæta við persónulegum prófílupplýsingum sem vistaðar eru í tækinu, t.d. nafni og samskiptaupplýsingum. Þetta þýðir að forritið veit hver þú ert og getur sent prófílupplýsingarnar þínar til annarra."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"líkamsskynjarar (s.s. hjartsláttarmælar)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Veitir forritinu aðgang að gögnum frá skynjurum sem fylgjast með líkamsstarfsemi þinni, svo sem hjartslætti."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lesa samfélagsstrauminn þinn"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Leyfir forriti að fá aðgang að og samstilla samfélagsuppfærslur þínar og vina þinna. Sýndu aðgát þegar þú deilir upplýsingum; þetta gerir forritinu kleift að lesa samskipti þín og vina þinna í netsamfélögum. Athugaðu: Ekki er víst að þessi heimild sé virt í öllum netsamfélögum."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrifa í samfélagsstrauminn þinn"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Leyfir forriti að birta samfélagsuppfærslur frá vinum þínum. Sýndu aðgát þegar þú deilir upplýsingum; þetta gerir forritinu kleift að útbúa skilaboð sem geta virst koma frá vini. Athugaðu: Ekki er víst að þessi heimild sé virt í öllum netsamfélögum."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lesa dagatalsviðburði og trúnaðarupplýsingar"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Leyfir forriti að lesa alla dagatalsviðburði sem vistaðir eru í spjaldtölvunni, þ. á m. þá sem vinir eða samstarfsmenn eiga. Þetta getur gert forritinu kleift að deila dagatalsgögnunum þínum burtséð frá því hvort þau innihalda trúnaðargögn eða viðkvæmar upplýsingar."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Leyfir forriti að lesa alla dagatalsviðburði sem vistaðir eru í sjónvarpinu, þ. á m. þá sem vinir eða samstarfsmenn eiga. Þetta getur gert forritinu kleift að deila dagatalsgögnunum þínum burtséð frá því hvort þau innihalda trúnaðargögn eða viðkvæmar upplýsingar."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Leyfir forriti að breyta kostum samstillingar fyrir reikning. Þetta er til dæmis hægt að nota til að kveikja á samstillingu forritsins Fólk við reikning."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lesa talnagögn um samstillingu"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Leyfir forriti að lesa talnagögn samstillingar fyrir reikning, þ. á m. feril samstillingaratvika og samstillt gagnamagn."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lesa hugtök sem þú hefur bætt við orðabókina"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Leyfir forriti að lesa öll orð, nöfn og setningar sem notandinn kann að hafa vistað í orðabók notanda."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"bæta orðum við orðabók notanda"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Leyfir forriti að skrifa ný orð inn í orðabók notanda."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lesa innihald USB-geymslunnar"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lesa innihald SD-kortsins"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Leyfir forriti að lesa innihald USB-geymslunnar."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3e18bcd..c17081e 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Posizione"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Le tue informazioni social"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accesso diretto alle informazioni sui tuoi contatti e sulle tue connessioni social."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesso al calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"invio e lettura di SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Archiviazione"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accesso a foto, contenuti multimediali e file sul dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dizionario utente"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lettura o scrittura delle parole contenute nel dizionario utente."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Segnalibri e cronologia"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accesso diretto ai segnalibri e alla cronologia del browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"registrazione audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotocamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"acquisizione di foto e registrazione di video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"esecuzione e gestione delle telefonate"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accesso alle informazioni sui tuoi parametri vitali e sulla tua attività fisica"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensori per il corpo"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accesso ai dati dei sensori sui tuoi parametri vitali"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Consente all\'applicazione di modificare il registro chiamate del tablet, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Consente all\'app di modificare il registro chiamate della TV, inclusi i dati sulle chiamate in arrivo e in uscita. Le app dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Consente all\'applicazione di modificare il registro chiamate del telefono, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lettura scheda contatti pers."</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Consente all\'applicazione di leggere informazioni del profilo personale memorizzate sul dispositivo, come il tuo nome e le tue informazioni di contatto. Ciò significa che l\'applicazione può identificarti e inviare le informazioni del tuo profilo ad altri."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modifica scheda contatti"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Consente all\'applicazione di modificare o aggiungere informazioni ai dati del profilo personale memorizzati sul dispositivo, come il tuo nome e le tue informazioni di contatto. Significa che l\'applicazione può identificarti e inviare le informazioni del tuo profilo ad altri."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensori per il corpo (come il cardiofrequenzimetro)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Consente all\'app di accedere ai dati relativi ai sensori che monitorano le tue condizioni fisiche, ad esempio la frequenza cardiaca."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lettura del tuo stream social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Consente all\'applicazione di accedere agli aggiornamenti dei social network tra te e i tuoi amici e di sincronizzarli. Fai attenzione quando condividi informazioni: questa autorizzazione consente all\'applicazione di leggere le comunicazioni tra te e i tuoi amici sui social network, indipendentemente dal livello di riservatezza. Nota. È possibile che questa autorizzazione non sia applicabile su tutti i social network."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrittura nel tuo stream social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Consente all\'applicazione di visualizzare gli aggiornamenti dei social network dai tuoi amici. Fai attenzione quando condividi informazioni: questa autorizzazione consente all\'applicazione di produrre messaggi apparentemente provenienti da un amico. Nota. È possibile che questa autorizzazione non sia applicabile su tutti i social network."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lettura di eventi di calendario e di informazioni riservate"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Consente all\'applicazione di leggere tutti gli eventi di calendario memorizzati sul tablet, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di condividere o salvare i dati del tuo calendario, a prescindere dal livello di riservatezza o privacy."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Consente all\'app di leggere tutti gli eventi di calendario memorizzati alla TV, inclusi gli eventi di amici o colleghi. L\'app potrebbe condividere o salvare i tuoi dati di calendario, a prescindere dal livello di riservatezza."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Consente a un\'applicazione di modificare le impostazioni di sincronizzazione per un account. Ad esempio, può servire per attivare la sincronizzazione dell\'applicazione Persone con un account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lettura statistiche di sincronizz."</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Consente a un\'applicazione di leggere le statistiche di sincronizzazione per un account, incluse la cronologia degli eventi di sincronizzazione e la quantità di dati sincronizzati."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lettura termini aggiunti al dizionario"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Consente all\'applicazione di leggere tutte le parole, le frasi e i nomi che l\'utente potrebbe aver memorizzato nel dizionario utente."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"aggiunta di parole al dizionario definito dall\'utente"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Consente all\'applicazione di scrivere nuove parole nel dizionario utente."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lettura contenuti archivio USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lettura contenuti scheda SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"L\'app può leggere i contenuti dell\'archivio USB."</string>
@@ -1547,7 +1528,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..7d46434 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"מיקום"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"גישה אל מיקום המכשיר הזה"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"מידע על הקשרים החברתיים שלך"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"גישה ישירה למידע על אנשי קשר וקשרים חברתיים שלך."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"יומן"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"גישה אל היומן"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"שליחה והצגה של הודעות SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"אחסון"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"גישה אל תמונות, מדיה וקבצים במכשיר שלך"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"מילון משתמש"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"קריאה או כתיבה של מילים במילון המשתמש."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"סימניות והיסטוריה"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"גישה ישירה אל סימניות והיסטוריית דפדפן."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"מיקרופון"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"הקלטת אודיו"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"מצלמה"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"צילום תמונות והקלטת וידאו"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"טלפון"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"התקשרות וניהול של שיחות טלפון"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"חיישנים"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"גישה אל מידע על הסימנים החיוניים והפעילות הגופנית שלך"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"חיישני גוף"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"גישה אל נתוני חיישנים של הסימנים החיוניים שלך"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"אחזור תוכן של חלון"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"בדוק את התוכן של חלון שאיתו אתה מבצע אינטראקציה."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"הפעלה של \'גילוי באמצעות מגע\'"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"מאפשר לאפליקציה לשנות את יומן השיחות של הטאבלט, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"מאפשרת לאפליקציה לשנות את יומן השיחות של הטלוויזיה, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות להשתמש בהרשאה זו כדי למחוק או לשנות את יומן השיחות שלך."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"מאפשר לאפליקציה לשנות את יומן השיחות של הטלפון, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"קריאת כרטיס איש הקשר שלך"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"מאפשר לאפליקציה לקרוא פרטים מהפרופיל האישי המאוחסנים במכשיר, כגון שמך ופרטי אנשי הקשר שלך. משמעות הדבר שהאפליקציה תוכל לזהות אותך ולשלוח את פרטי הפרופיל שלך לאנשים אחרים."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"שינוי כרטיס איש הקשר שלך"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"מאפשר לאפליקציה לשנות או להוסיף נתונים לפרטי הפרופיל האישי המאוחסנים במכשיר, כגון שמך ופרטי הקשר שלך. משמעות הדבר שהאפליקציה יכולה לזהות אותך ועשוי לשלוח את פרטי הפרופיל שלך לאנשים אחרים."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"חיישני גוף (כמו מוניטורים עבור קצב לב)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"מאפשר לאפליקציה לגשת אל נתוני חיישנים העוקבים אחר מצבך הגופני, כמו קצב הלב."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"קריאת הזרם החברתי שלך"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"מאפשר לאפליקציה גישה ויכולת סנכרון של עדכונים חברתיים שאתה וחבריך מבצעים. היזהר בעת שיתוף מידע -- הדבר מתיר לאפליקציה לקרוא התכתבויות בינך ובין חבריך ברשתות חברתיות, ללא התחשבות בסודיות. שים לב: ייתכן שאישור זה לא נאכף בכל הרשתות החברתיות."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"כתיבה בזרם החברתי שלך"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"מאפשר לאפליקציה להציג עדכונים חברתיים מהחברים שלך. היזהר בעת שיתוף מידע -- הדבר מאפשר לאפליקציה ליצור הודעות שעשויות להיראות כאילו שנשלחו מחבר. שים לב: ייתכן אישור זה לא נאכף בכל הרשתות החברתיות."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"קריאת אירועי יומן וגם מידע סודי"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"מאפשר לאפליקציה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, כולל אלה של חברים ועמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשתף או לשמור את נתוני היומן שלך, ללא התחשבות בסודיות או ברגישות."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"מאפשרת לאפליקציה לקרוא את כל אירועי היומן השמורים בטלוויזיה שלך, כולל אירועים של חברים ועמיתים. הרשאה זו עשויה לאפשר לאפליקציה לשתף או לשמור נתונים מהיומן שלך, בלי קשר לסודיות או לרגישות הנתונים."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"מאפשר לאפליקציה לשנות את הגדרות הסנכרון של חשבון. לדוגמה, ניתן להשתמש בכך על מנת להפעיל סנכרון של האפליקציה \'אנשים\' עם חשבון כלשהו."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"קרא את הנתונים הסטטיסטיים של הסינכרון"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"מאפשר לאפליקציה לקרוא את סטטיסטיקת הסנכרון של חשבון, כולל היסטוריית אירועי הסנכרון וכמות הנתונים שסונכרנה."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"קריאת מונחים שהוספת למילון"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"מאפשר לאפליקציה לקרוא את כל המילים, השמות והביטויים שהמשתמש אחסן במילון המשתמש."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"הוספת מילים למילון מוגדר-משתמש"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"מאפשר לאפליקציה לכתוב מילים חדשות במילון המשתמש."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"קריאת התוכן של אחסון ה-USB שלך"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"קריאת התוכן של כרטיס ה-SD שלך"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"מאפשר לאפליקציה לקרוא את תוכן אחסון ה-USB שלך."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 009f4f0..67f9595 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置情報"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"この端末の位置情報にアクセス"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ソーシャル情報"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"連絡先とソーシャルコネクションに関する情報に直接アクセスします。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"カレンダー"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"カレンダーへのアクセス"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMSメッセージの送信と表示"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ストレージ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"端末上の写真、メディア、ファイルへのアクセス"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"単語リスト"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"単語リストの語句の読み取りまたは書き込みを行います"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ブックマークと履歴"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ブックマークとブラウザの履歴に直接アクセスします。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"マイク"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"音声の録音"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"カメラ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"写真の撮影と動画の記録"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"通話の発信と管理"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"センサー"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"バイタルサインや身体活動に関する情報へのアクセス"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ボディーセンサー"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"バイタルサインに関するセンサーデータへのアクセス"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ウィンドウコンテンツの取得"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"タッチガイドの有効化"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"タブレットの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"テレビの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"携帯端末の通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"自分の連絡先カードの読み取り"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"端末に保存されている個人のプロフィール情報(名前、連絡先情報など)の読み取りをアプリに許可します。これにより、アプリがユーザーの身元を特定できるようになり、プロフィール情報を第三者に転送する可能性があります。"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"自分の連絡先カードの変更"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"端末に保存されている個人のプロフィール情報(名前、連絡先情報など)の変更と追加をアプリに許可します。これにより、アプリがユーザーの身元を特定できるようになり、プロフィール情報を第三者に転送する可能性があります。"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ボディーセンサー(心拍数モニターなど)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"心拍数など、身体状態を監視するセンサーからのデータにアクセスすることをアプリに許可します。"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ソーシャルストリームを読む"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"あなたや友だちのソーシャル更新情報へのアクセスと同期をアプリに許可します。情報の共有は慎重に行ってください。これを許可すると、あなたと友だちがソーシャルネットワークで行ったやり取りを、機密性に関係なくアプリから読み取ることができるようになります。注: この許可は、一部のソーシャルネットワークでは適用されない場合があります。"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ソーシャルストリームに書く"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"友だちのソーシャル更新情報の表示をアプリに許可します。情報の共有は慎重に行ってください。これによりアプリは、友だちから発信されたかのようなメッセージを作成できるようになります。注: この許可は、一部のソーシャルネットワークでは適用されない場合があります。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"カレンダーの予定と機密情報の読み取り"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"タブレットに保存されているカレンダーの予定(友だちや同僚の予定も含めすべて)を読み取ることをアプリに許可します。これにより、アプリがカレンダーのデータを機密性に関係なく共有または保存できるようになる可能性があります。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"テレビに保存されているカレンダーの予定(友だちや同僚の予定も含めすべて)を読み取ることをアプリに許可します。これにより、アプリがカレンダーのデータを機密性に関係なく共有または保存できるようになる可能性があります。"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"アカウントの同期設定の変更をアプリに許可します。たとえば、連絡帳アプリとアカウントの同期を有効にするために使用できます。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"同期統計の読み取り"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"アカウントの同期ステータス(同期イベントの履歴、同期されたデータの量など)の読み取りをアプリに許可します。"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"辞書に追加された語句の読み取り"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"単語リストに登録されているすべての語句や名前を読み取ることをアプリに許可します。"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"単語リストへの語句の追加"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"単語リストに新しい語句を書き込むことをアプリに許可します。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USBストレージの読み取り"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SDカードのコンテンツの読み取り"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"USBストレージのコンテンツの読み取りをアプリに許可します。"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 0224308..b06efd8 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"მდებარეობა"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"მოწყობილობის მდებარეობაზე წვდომა"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"თქვენი სოციალური ინფორმაცია"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"თქვენს კონტაქტებისა და სოციალურ კავშირების შესახებ ინფორმაციაზე პირდაპირი წვდომა."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"თქვენს კალენდარზე წვდომა"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS შეტყობინებების გაგზავნა და ნახვა"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"შესანახი სივრცე"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"თქვენს მოწყობილობაზე არსებულ ფოტოებზე, მედიასა და ფაილებზე წვდომა"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"მომხმარებლის ლექსიკონი"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"მომხმარებლის ლექსიკონში სიტყვების წაკითხვა ან ჩაწერა."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"სანიშნეები და ისტორია"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"პირდაპირი წვდომა სანიშნეებსა და ბრაუზერის ისტორიაზე"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"მიკროფონი"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"აუდიოს ჩაწერა"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"კამერა"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ფოტოებისა და ვიდეოების გადაღება"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ტელეფონი"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"სატელეფონო ზარების განხორციელება და მართვა"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"სენსორები"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"თქვენი სასიცოცხლო ფუნქციებისა და ფიზიკური აქტივობის ინფორმაციაზე წვდომა"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"სხეულის სენსორები"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"თქვენი სასიცოცხლო ფუნქციების შესახებ სენსორის მონაცემებზე წვდომა"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ფანჯრის კონტენტის მოძიება"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"შეამოწმეთ იმ ფანჯრის კონტექტი, რომელშიც მუშაობთ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"„შეხებით აღმოჩენის“ ჩართვა"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"აპს შეეძლება, შეცვალოს თქვენი ტაბლეტის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ნებას რთვს აპლიკაციას, შეცვალოს თქვენი ტელევიზორის ზარების ჟურნალი, შემომავალი და გამავალი ზარების მონაცემთა ჩათვლით. მავნე აპლიკაციებს შეუძლიათ ამოშალონ ან შეცვალონ თქვენი ზარების ჟურნალი."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"აპს შეეძლება, შეცვალოს თქვენი ტელეფონის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"თქვენი საკონტაქტო ინფორმაციის ნახვა"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის წაკითხვა, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"თქვენი საკონტაქტო ინფორმაციის შეცვლა"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის შეცვლა ან დამატება, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"სხეულის სენსორები (მაგ. გულისცემის მონიტორები)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"აპისთვის ნების დართვა, რათა მას ჰქონდეს წვდომა თქვენი ფიზიკური მდგომარეობის მონიტორინგის სენსორების მონაცემებზე."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"სოციალური ნაკადის წაკითხვა"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"აპს შეეძლება თქვენი და თქვენი მეგობრების სოციალური განახლებებთან წვდომა და სინქრონიზაცია. ინფორმაციის გაზიარებისას იყავით ფრთხიად - აპს ექნება შესაძლებლობა, რომ წაიკითხოს სოციალურ ქსელებში კომუნიკაცია თქვენსა და თქვენს მეგობრებს შორის კონფიდენციალურობის მიუხედავად. შენიშვნა: ეს უფლება შესაძლოა ვერ იყოს გამოყენებული ყველა სოციალურ ქსელში."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"თქვენს სოციალურ მაუწყებლობაზე დაწერა"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"აპს შეეძლება, გიჩვენოთ თქვენი მეგობრების სოციალური სიახლეები. ფრთხილად იყავით ინფორმაციის გაზიარებისას - აპს შეუძლია შექმნას შეტყობინება, რომელიც თითქოსდა მეგობრისგან არის მოწერილი. შენიშვნა: ეს ნებართვა არ შეიძლება შესრულდეს ყველა სოციალურ ქსელში."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"კალენდრის ღონისძიებებისა და კონფიდენციალური ინფორმაციის წაკითხვა"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"აპს შეეძლება, წაიკითხოს თქვენ ტაბლეტზე შენახული კალენდრის ყველა მოვლენა, მათ შორის მეგობრებისა და თანამშრომლების მოვლენებიც. ამან შეიძლება უფლება მისცეს აპს, გააზიაროს ან შეინახოს თქვენი კალენდრის მონაცემები, მიუხედავად კონფიდენციალურობისა თუ მგრძობიარობისა."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ნებას რთავს აპლიკაციას, წაიკითხოს თქვენს ტელევიზორში განთავსებული კალენდარული მოვლენები, მეგობრებისა თუ თანამშრომლების ჩათვლით. ამან შესაძლოა ნება დართოს აპლიკაციას გააზიროს ან შეინახოს კალენდარული მონაცემები, მიუხედავად მათი კონფიდენცალურობისა და სენსიტიურობის."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"აპს შეეძლება, შეცვალოს ანგარიშის სინქრონიზაციის პარამეტრები. მაგალითად, მისი გამოყენება შეიძლება ანგარიშის People აპთან სინქრონიზაციის ჩასართავად."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"სინქრონიზაციის სტატისტიკების წაკითხვა"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"აპს შეეძლება ანგარიშის სინქრონიზაციის სტატისტიკის, მათ შორის სინქრონიზაციის მოვლენების ისტორიისა და სინქრონიზაციისას გადაცემული მონაცემების რაოდენობის წაკითხვა."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ლექსიკონში თქვენი დამატებული ტერმინების ნახვა"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"აპს შეეძლება წაიკითხოს ყველა სიტყვა, სახელი და ფრაზა, რომელიც შეიძლება მომხმარებელმა შეიტანა მომხმარებლის ლექსიკონში."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"მომხმარებლისთვის განკუთვნილ ლექსიკონში სიტყვების დამატება."</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"აპს შეეძლება ახალი სიტყვების დამატება მომხმარებლის ლექსიკონში."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"თქვენი USB მეხსიერების კონტენტის წაკითხვა"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"თქვენი SD ბარათის კონტენტის წაკითხვა"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"აპი წაიკითხავს USB კონტენტს."</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index f2d15fe..0486890 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Орын"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"бұл құрылғының орнына кіру"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Сіздің әлеуметтік ақпаратыңыз"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Байланыстарыңыз бен әлеуметтік контактілеріңіз туралы ақпаратқа тікелей қол жетімділік."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнтізбе"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнтізбеге кіру"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS хабарларын жіберу және көру"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Жад"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"құрылғыдағы фотосуреттерге, мультимедиаға және файлдарға қол жеткізу"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Пайдаланушы сөздігі"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Пайдаланушы сөздігінде сөздерді оқыңыз не жазыңыз."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Бетбелгілер және Тарих"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Бетбелгілер мен браузерге тікелей қол жетімділік."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио жазу"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"суретке түсіріп, бейне жазу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"қоңырау шалу және телефон қоңырауларын басқару"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлар"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ағза күйінің көрсеткіштері мен дене белсенділігі туралы ақпаратқа қол жеткізу"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Дене датчиктері"</string>
+ <!-- no translation found for permgroupdesc_sensors (7147968539346634043) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмұнын оқып отыру."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ашық тұрған терезе мазмұнын тексеру."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Түртілген элементтерді дыбыстау функциясын қосу"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Қолданбаға сіздің планшетіңіздегі қоңырау тіркеуін, келетін немесе шығатын қоңыраулар туралы деректерді қоса, өзгерту мүмкіндігін береді. Залалды қолданбалар бұны сіздің қоңырау тіркеуіңізді өшіру үшін қолдануы мүмкін."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Қолданбаға ТД қоңыраулар журналын, соның ішінде, кіріс және шығыс қоңыраулар туралы деректерді өзгертуге рұқсат етеді. Зиянкес қолданбалар мұны қоңыраулар журналын өшіру немесе өзгерту үшін пайдалануы мүмкін."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Қолданбаға сіздің телефоныңыздың қоңырау тіркеуін, келетін немесе шығатын қоңыраулар туралы деректерді қоса, өзгерту мүмкіндігін береді. Залалды қолданбалар бұны сіздің қоңырау тіркеуіңізді өшіру үшін қолдануы мүмкін."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"өзіңіздің контакт картаңызды оқу"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Қолданбаға құрылғыда сақталған сіздің аты-жөніңіз және байланыс ақпаратыңыз сияқты жеке ақпаратты оқу мүмкіндігін береді. Бұл қолданба сізді анықтап, сіз туралы жеке ақпаратты басқаларға жібере алады дегенді білдіреді."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"өзіңіздің байланыс картаңызды өзгерту"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Қолданбаға құрылғыда сақталған сіздің аты-жөніңіз және байланыс ақпаратыңыз сияқты жеке ақпаратты өзгерту немесе қосу мүмкіндігін береді. Бұл - қолданба сізді анықтап, сіз туралы жеке ақпаратты басқаларға жібере алады дегенді білдіреді."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"дене сен-ры (жүрек соғу жиіл. мон-ры сияқты)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Қолданбаға жүрек соғу жиілігіңіз сияқты дене күйіңізді бақылайтын сенсорлардың деректеріне қатынасуға рұқсат етеді."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"әлеуметтік ағымды оқу"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Қолданбаға сіз және достарыңыздың әлеуметтік жаңартуларына кіру және синхрондау мүмкіндігін береді. Ақпарат бөліскенде абай болыңыз -- бұл қолданбаға сіз және достарыңызды әлеуметтік желілердегі қарым-қатынасты, құпиялығына қарамастан, оқу мүмкіндігін берді. Есіңізде болсын: бұл рұқсатты барлық әлеуметтік желілер қолданбайды."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"әлеуметтік ағынға жазу"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Қолданбаға сіздің достарыңыздың әлеуметтік желі жаңартуларын көрсету мүмкіндігін береді. Ақпарат бөліскенде абай болыңыз -- бұл қолданбаға сіздің досыңыздан келген сияқты болып көрінетін хабар жіберу мүмкіндігін береді. Есіңізде болсын: әлеуметтік желілер бұл рұқсатты қолданбауы мүмкін."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"күнтізбе шаралары мен құпия ақпаратты оқу"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Қолданбаға планшетте сақталған барлық күнтізбе шараларын, достар немесе әріптестердің шараларын қоса, оқу мүмкіндігін береді. Бұл қолданбаға күнтізбе деректерін, құпиялығы мен сезімталдығына қарамастан, бөлісу немесе сақтау мүмкіндігін беруі ықтимал."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Қолданбаға теледидарда сақталған бүкіл күнтізбе оқиғаларын, соның ішінде, достардыкін немесе әріптестердікін, оқуға рұқсат етеді. Бұл қолданбаға құпиялығына немесе сезімталдығына қарамастан күнтізбе деректеріңізді бөлісуге рұқсат етуі мүмкін."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Қолданбаға есептік жазбаның синхрондау параметрлерін жөндеу мүмкіндігін береді. Мысалы, бұл People қолданбасын есептік жазбамен синхрондауды қосу үшін қолданылуы мүмкін."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"үйлестіру санақтық ақпаратын оқу"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Қолданбаға есептік жазбаның синхрондалу статистикаларын, оның ішінде синхрондау шараларының тарихы және қанша дерек синхрондалғаны жайлы, оқу мүмкіндігін береді."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"сөздікке сіз қосқан шарттарды оқу"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Қолданбаға пайдаланушы сөздігінде сақталған барлық сөздер, аттар және фразаларды оқу мүмкіндігін береді."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"пайдаланушы анықтаған сөздікке сөздер қосу"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Қолданбаға пайдаланушы сөздігіне жаңа сөздерді жазуға рұқсат береді."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"Өзіңіздің USB жадыңыздың мазмұнын оқу"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"Өзіңіздің SD картаңыздың мазмұнын оқу"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Қолданбаға USB жадыңыздың мазмұнын оқу мүмкіндігін береді."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index e9c2a05..bbc0805 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ទីតាំង"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ចូលដំណើរការទីតាំងរបស់ឧបករណ៍នេះ"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មានសង្គមរបស់អ្នក"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីទំនាក់ទំនង និងការភ្ជាប់សង្គមរបស់អ្នក។"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"សារ SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ផ្ញើ និងមើលសារ SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ការផ្ទុក"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ចូលដំណើការរូបភាព មេឌៀ និងឯកសារនៅលើឧបករណ៍របស់អ្នក"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"វចនានុក្រមអ្នកប្រើ"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"អាន ឬសរសេរនៅក្នុងវចនានុក្រមអ្នកប្រើ។"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ចំណាំ និងប្រវត្តិ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ចូលដំណើរការចំណាំ និងប្រវត្តិកម្មវិធីអ៊ីនធឺណិតដោយផ្ទាល់។"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"មីក្រូហ្វូន"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ថតសំឡេង"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ម៉ាស៊ីនថត"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ថតរូប និងថតវីដេអូ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ទូរស័ព្ទ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ហៅទូរស័ព្ទ និងគ្រប់គ្រងការហៅទូរស័ព្ទ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ឧបករណ៍ចាប់សញ្ញា"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ចូលដំណើរការព័ត៌មានអំពីស្ថានភាពសុខភាព និងសកម្មភាពរាងកាយរបស់អ្នក"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ឧបករណ៍ចាប់សញ្ញារាងកាយ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ចូលដំណើរការទិន្នន័យឧបករណ៍ចាប់សញ្ញាអំពីស្ថានភាពសុខភាពរបស់អ្នក"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ទៅយកមាតិកាបង្អួច"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ពិនិត្យមាតិកាបង្អួចដែលអ្នកកំពុងទាក់ទងជាមួយ។"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"បើកការរកមើលដោយប៉ះ"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យកម្មវិធីកែបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នករួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីហៅរបស់អ្នក។"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"អនុញ្ញាតឲ្យកម្មវិធីកែសម្រួលកំណត់ហេតុហៅទូរស័ព្ទទូរទស្សន៍របស់អ្នក ដោយរាប់បញ្ចូលទាំងទិន្នន័យអំពីការហៅចូល និងការហៅចេញ។ កម្មវិធីព្យាបាទអាចប្រើវាដើម្បីលុប ឬកែសម្រួលកំណត់ហេតុការហៅទូរស័ព្ទរបស់អ្នក។"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ឲ្យកម្មវិធីកែបញ្ជីហៅនៃទូរស័ព្ទរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីការហៅរបស់អ្នក។"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"អានកាតទំនាក់ទំនងផ្ទាល់ខ្លួនរបស់អ្នក"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ឲ្យកម្មវិធីអានព័ត៌មានប្រវត្តិរូបផ្ទាល់ខ្លួនដែលមានលើឧបករណ៍របស់អ្នក ដូចជា ឈ្មោះ និងព័ត៌មានទំនាក់ទំនង។ វាមានន័យថា កម្មវិធីអាចកំណត់អ្នក និងអាចផ្ញើព័ត៌មានប្រវត្តិរូបរបស់អ្នកទៅអ្នកផ្សេង។"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"កែកាតទំនាក់ទំនងផ្ទាល់ខ្លួនរបស់អ្នក"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ឲ្យកម្មវិធីប្ដូរ ឬបន្ថែមព័ត៌មានប្រវត្តិរូបផ្ទាល់ខ្លួនដែលបានរក្សាទុកក្នុងឧបករណ៍របស់អ្នក ដូចជា ឈ្មោះ និងព័ត៌មានទំនាក់ទំនងរបស់អ្នក។ នេះមានន័យថាកម្មវិធីអាចកំណត់អ្នក និងផ្ញើព័ត៌មានប្រវត្តិរូបរបស់អ្នកទៅអ្នកផ្សេង។"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ឧបករណ៍ចាប់សញ្ញារាងកាយ(ដូចជាម៉ាស៊ីនវាស់ចង្វាក់បេះដូង)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ឲ្យកម្មវិធីចូលដំណើរការទិន្នន័យពីឧបករណ៍ចាប់សញ្ញាដែលតាមដានលក្ខខណ្ឌសុខភាពរបស់អ្នក ដូចជាចង្វាក់បេះដូង។"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"អានចរន្តសង្គមរបស់អ្នក"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ឲ្យកម្មវិធីចូលដំណើរការ និងធ្វើសមកាលកម្មបច្ចុប្បន្នភាពសង្គមពីអ្នក និងមិត្តភ័ក្ដិ។ ប្រយ័ត្នពេលចែករំលែកព័ត៌មាន វាអនុញ្ញាតឲ្យកម្មវិធីអានការទាក់ទងរវាងអ្នក និងមិត្តភ័ក្ដិលើបណ្ដាញសង្គម ទាក់ទងនឹងព័ត៌មានសម្ងាត់។ ចំណាំ៖ សិទ្ធិនេះមិនអាចត្រូវបានអនុវត្តលើបណ្ដាញសង្គមទាំងអស់បានទេ។"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"សរសេរទៅចរន្តសង្គមរបស់អ្នក"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ឲ្យកម្មវិធីបង្ហាញបច្ចុប្បន្នភាពសង្គមពីមិត្តភ័ក្ដិរបស់អ្នក។ ប្រយ័ត្នពេលចែករំលែកព័ត៌មាន វាឲ្យកម្មវិធីបង្កើតសារដែលអាចបង្ហាញថាមកពីមិត្តភ័ក្ដិ។ ចំណាំ៖ សិទ្ធិនេះមិនអាចប្រើលើបណ្ដាញសង្គមបានទេ។"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"អានព្រឹត្តិការណ៍ប្រតិទិននិងព័ត៌មានសម្ងាត់"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ឲ្យកម្មវិធីអាចព្រឹត្តិការណ៍ប្រតិទិនទាំងអស់ដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក រួមមានមិត្តភ័ក្ដិ និងមិត្តរួមការងារ។ វាអាចឲ្យកម្មវិធីចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នកដោយមិនគិតពីការសម្ងាត់ ឬការយល់ដឹង។"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"អនុញ្ញាតឲ្យកម្មវិធីអានព្រឹត្តិការណ៍ប្រតិទិនទាំងអស់ដែលបានផ្ទុកនៅលើទូរទស្សន៍របស់អ្នក ដោយរាប់បញ្ចូលទាំងព្រឹត្តិការណ៍របស់មិត្តភ័ក្ត និងមិត្តរួមការងាររបស់អ្នក។ វាអាចអនុញ្ញាតឲ្យកម្មវិធីចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នក ដោយមិនគិតថាវាជាព័ត៌មានសម្ងាត់ ឬរសើបក៏ដោយ។"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ឲ្យកម្មវិធីកែការកំណត់ធ្វើសមកាលកម្មសម្រាប់គណនី។ ឧទាហរណ៍ វាអាចត្រូវបានប្រើដើម្បីបើកការធ្វើសមកាលកម្មកម្មវិធីរបស់មនុស្សជាមួយគណនី។"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"អានស្ថិតិធ្វើសមកាលកម្ម"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ឲ្យកម្មវិធីអានស្ថានភាពធ្វើសមកាលកម្មសម្រាប់គណនី រួមមានព្រឹត្តិការណ៍ប្រវត្តិធ្វើសមកាលកម្ម និងទំហំទិន្នន័យបានធ្វើសមកាលកម្ម។"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"អានពាក្យដែលអ្នកបានបន្ថែមទៅវចនានុក្រម"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ឲ្យកម្មវិធីអានពាក្យ ឈ្មោះ និងឃ្លាទាំងអស់ដែលអ្នកប្រើអាចរក្សាទុកក្នុងវចនានុក្រមអ្នកប្រើ។"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"បន្ថែមពាក្យទៅវចនានុក្រមកំណត់ដោយអ្នកប្រើ"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ឲ្យកម្មវិធីសរសេរពាក្យថ្មីក្នុងវចនានុក្រមអ្នកប្រើ។"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"អានមាតិកាឧបករណ៍ផ្ទុកយូអេសប៊ីរបស់អ្នក"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"អានមាតិកាកាតអេសឌីរបស់អ្នក"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ឲ្យកម្មវិធីអានមាតិកាឧបករណ៍ផ្ទុកយូអេសប៊ីរបស់អ្នក។"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 9b7e4a9..952f63c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ಸ್ಥಳ"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಮಾಹಿತಿ"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಸಾಮಾಜಿಕ ಸಂಪರ್ಕಗಳ ಕುರಿತ ಮಾಹಿತಿಗೆ ನೇರ ಪ್ರವೇಶ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ಕ್ಯಾಲೆಂಡರ್"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ಸಂಗ್ರಹಣೆ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಫೈಲ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"ಬಳಕೆದಾರರ ನಿಘಂಟು"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ಬಳಕೆದಾರರ ನಿಘಂಟಿನಲ್ಲಿನ ಪದಗಳನ್ನು ಓದಿ ಮತ್ತು ಬರೆಯಿರಿ."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಇತಿಹಾಸ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಬ್ರೌಸರ್ ಇತಿಹಾಸಕ್ಕೆ ನೇರ ಪ್ರವೇಶ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ಮೈಕ್ರೋಫೋನ್"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ಕ್ಯಾಮರಾ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಿರಿ ಹಾಗೂ ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ಫೋನ್"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ಸಂವೇದಕಗಳು"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ನಿಮ್ಮ ಮಹತ್ವಪೂರ್ಣ ಚಿಹ್ನೆಗಳು ಮತ್ತು ದೈಹಿಕ ಚಟುವಟಿಕೆ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ದೇಹ ಸೆನ್ಸರ್ಗಳು"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸಾರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳುತ್ತದೆ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ನೀವು ಸಂವಹನ ನಡೆಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯವನ್ನು ಪರೀಕ್ಷಿಸಿ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ಸ್ಪರ್ಶಿಸುವ ಮೂಲಕ ಎಕ್ಸ್ಪ್ಲೋರ್ ಆನ್ ಮಾಡಿ"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತು ಡೇಟಾ ಸೇರಿದಂತೆ ನಿಮ್ಮ ಟಿವಿಯ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಫೋನ್ನ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ನಿಮ್ಮದೇ ಸಂಪರ್ಕದ ಕಾರ್ಡ್ ಓದಿ"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಹೆಸರು ಮತ್ತು ಸಂಪರ್ಕ ಮಾಹಿತಿಯಂತಹ, ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದರರ್ಥ, ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮನ್ನು ಗುರುತಿಸಬಹುದು ಮತ್ತು ಇತರರಿಗೆ ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಕಳುಹಿಸಬಹುದು."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ನಿಮ್ಮದೇ ಸಂಪರ್ಕದ ಕಾರ್ಡ್ ಮಾರ್ಪಡಿಸಿ"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಹೆಸರು ಹಾಗೂ ಸಂಪರ್ಕ ಮಾಹಿತಿಯಂತಹ, ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಬದಲಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಅಂದರೆ, ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮನ್ನು ಗುರುತಿಸಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಇತರರಿಗೆ ಕಳುಹಿಸಬಹುದು ಎಂದರ್ಥ."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ದೇಹದ ಸಂವೇದಗಳು (ಹೃದಯದ ರೇಟ್ ಮಾನಿಟರ್ಗಳಂತಹ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ನಿಮ್ಮ ಹೃದಯ ಬಡಿತದಂತಹ ನಿಮ್ಮ ದೈಹಿಕ ಸ್ಥಿತಿಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುವ ಸೆನ್ಸರ್ಗಳಿಂದ ಡೇಟಾ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಸ್ಟ್ರೀಮ್ ಓದಿರಿ"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ನೀವು ಮತ್ತು ನಿಮ್ಮ ಸ್ನೇಹಿತರ ಸಾಮಾಜಿಕ ನವೀಕರಣಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಮತ್ತು ಸಿಂಕ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳುವಾಗ ಜಾಗರೂಕರಾಗಿರಿ -- ಇದು ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಸಾಮಾಜಿಕ ನೆಟ್ವರ್ಕ್ಗಳಲ್ಲಿ ನೀವು ಮತ್ತು ನಿಮ್ಮ ಸ್ನೇಹಿತರ ನಡುವೆ ನಡೆದಿರುವ ಸಂವಹನವನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಗಮನಿಸಿ: ಈ ಅನುಮತಿಯನ್ನು ಎಲ್ಲಾ ಸಾಮಾಜಿಕ ನೆಟ್ವರ್ಕ್ಗಳಲ್ಲಿ ಜಾರಿಗೊಳಿಸದೇ ಇರಬಹುದು."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಸ್ಟ್ರೀಮ್ನಲ್ಲಿ ಬರೆಯಿರಿ"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ನಿಮ್ಮ ಸ್ನೇಹಿತರ ಸಾಮಾಜಿಕ ನವೀಕರಣಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳುವಾಗ ಜಾಗರೂಕರಾಗಿರಿ -- ಇದು ಸ್ನೇಹಿತರು ಕಳುಹಿಸಿರುವಂತಹ ಸಂದೇಶಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಗಮನಿಸಿ: ಈ ಅನುಮತಿಯನ್ನು ಎಲ್ಲಾ ಸಾಮಾಜಿಕ ನೆಟ್ವರ್ಕ್ಗಳಲ್ಲಿ ಜಾರಿಗೊಳಿಸದೇ ಇರಬಹುದು."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳು ಅಲ್ಲದೇ ಗೌಪ್ಯತೆ ಮಾಹಿತಿಯನ್ನು ಓದಿರಿ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ಸ್ನೇಹಿತರ ಅಥವಾ ಸಹೋದ್ಯೋಗಿಗಳ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳೂ ಸೇರಿದಂತೆ, ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸಿಕೊಡುತ್ತದೆ. ಇದು ಗೌಪ್ಯತೆ ಮತ್ತು ಸೂಕ್ಷ್ಮತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಮತ್ತು ಉಳಿಸಿಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸಬಹುದು."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳು, ಸ್ನೇಹಿತರು ಅಥವಾ ಸಹ-ಕೆಲಸಗಾರರನ್ನು ಒಳಗೊಂಡಂತೆ ಅಪ್ಲಿಕೇಶನ್ ಓದಲು ಅನುಮತಿಸುತ್ತದೆ. ಗೌಪ್ಯತೆ ಅಥವಾ ಸಂವೇದನೆಯನ್ನು ಪರಿಗಣಿಸದೆ ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಅಥವಾ ಉಳಿಸಲು ಇದು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ಖಾತೆಗೆ ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಖಾತೆಯನ್ನು ಹೊಂದಿರುವ ವ್ಯಕ್ತಿಗಳ ಸಿಂಕ್ ಸಕ್ರಿಯಗೊಳಿಸಲು ಇದನ್ನು ಬಳಸಬಹುದಾಗಿದೆ."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ಸಿಂಕ್ ಅಂಕಿಅಂಶಗಳನ್ನು ಓದಿರಿ"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ಸಿಂಕ್ ಈವೆಂಟ್ಗಳ ಇತಿಹಾಸ ಮತ್ತು ಎಷ್ಟು ಪ್ರಮಾಣದ ಡೇಟಾವನ್ನು ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ ಎಂಬುದು ಸೇರಿದಂತೆ, ಒಂದು ಖಾತೆಗಾಗಿ ಸಿಂಕ್ ಅಂಕಿಅಂಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ನೀವು ನಿಘಂಟಿಗೆ ಸೇರಿಸಿದ ಪದಗಳನ್ನು ಓದಿ"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ಬಳಕೆದಾರರು ಬಳಕೆದಾರ ನಿಘಂಟಿನಲ್ಲಿ ಸಂಗ್ರಹಿಸಿರಬಹುದಾದ ಎಲ್ಲಾ ಪದಗಳು, ಹೆಸರುಗಳು ಮತ್ತು ನುಡಿಗಟ್ಟುಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ಬಳಕೆದಾರ-ನಿರ್ಧರಿತ ನಿಘಂಟಿಗೆ ಪದಗಳನ್ನು ಸೇರಿಸಿ"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ಬಳಕೆದಾರರ ನಿಘಂಟಿನಲ್ಲಿ ಹೊಸ ಪದಗಳನ್ನು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ನಿಮ್ಮ USB ಸಂಗ್ರಹಣೆಯ ವಿಷಯಗಳನ್ನು ಓದಿ"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ನಿಮ್ಮ SD ಕಾರ್ಡ್ನ ವಿಷಯಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ನಿಮ್ಮ USB ಸಂಗ್ರಹಣೆಯ ವಿಷಯಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -902,7 +883,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 +1047,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 +1212,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 +1259,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..92c1e8e 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"위치"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"이 기기의 위치에 액세스하기"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"소셜 정보"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"내 연락처 및 소셜 친구의 개인 정보에 직접 액세스합니다."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"캘린더"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더 액세스"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS 메시지를 전송하고 봅니다."</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"저장"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"기기의 사진, 미디어, 파일에 액세스합니다."</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"사용자 사전"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"사용자 사전의 단어를 읽거나 씁니다."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"북마크 및 기록"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"북마크 및 브라우저 기록에 직접 액세스합니다."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"마이크"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오 녹음"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"카메라"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 찍기 및 동영상 녹화"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"센서"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"생체 신호 및 물리적 활동 정보에 액세스합니다."</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"앱에서 수신 및 발신 통화 데이터를 포함하여 TV의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 삭제하거나 수정할 수도 있습니다."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"나만의 연락처 카드 읽기"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"앱이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 읽을 수 있도록 허용합니다. 이는 앱이 사용자를 확인할 수 있으며 다른 사용자에게 해당 프로필 정보를 전송할 수도 있다는 것을 의미합니다."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"나만의 연락처 카드 수정"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"앱이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 변경 또는 추가할 수 있도록 허용합니다. 이는 앱이 사용자를 확인하고 다른 사용자에게 해당 프로필 정보를 전송할 수 있다는 것을 의미합니다."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"신체 센서(예: 심박수 모니터)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"앱이 심박수와 같은 신체 상태를 모니터링하는 센서의 데이터에 액세스하도록 허용합니다."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"소셜 스트림 읽기"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"앱이 사용자와 친구의 최신 소셜 소식에 액세스하고 동기화할 수 있도록 허용합니다. 이 경우 앱이 비밀유지와 관계 없이 소셜 네트워크에서 사용자와 친구가 주고받는 내용을 읽을 수 있으므로, 정보를 공유할 때 주의해야 합니다. 참고: 이 권한이 적용되지 않는 소셜 네트워크도 있습니다."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"소셜 스트림에 쓰기"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"앱이 친구의 소셜 소식을 표시할 수 있도록 허용합니다. 이 경우 친구로부터 나온 것으로 보이는 메시지를 생성할 수 있으므로, 정보를 공유할 때 주의해야 합니다. 참고: 이 권한이 적용되지 않는 소셜 네트워크도 있습니다."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"캘린더 일정 및 기밀정보 읽기"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"앱이 친구나 동료의 일정을 포함하여 태블릿에 저장된 모든 캘린더 일정을 읽을 수 있도록 허용합니다. 이 경우 앱이 비밀유지 또는 기밀성을 무시하고 캘린더 데이터를 공유 또는 저장할 수도 있습니다."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"앱이 친구 및 동료들의 일정을 포함하여 TV에 저장된 모든 캘린더 일정을 읽을 수 있도록 허용합니다. 이 경우 앱이 데이터의 민감성 또는 기밀성과 상관없이 캘린더 데이터를 공유하거나 저장할 수 있게 됩니다."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"앱이 계정의 동기화 설정을 수정할 수 있도록 허용합니다. 예를 들어, 계정에서 주소록 앱을 동기화할 목적으로 앱이 사용될 수 있습니다."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"동기화 통계 읽기"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"앱이 동기화된 일정의 기록이나 동기화된 데이터의 양 등을 포함하여 계정의 동기화 통계를 읽을 수 있도록 허용합니다."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"사전에 추가한 단어 읽기"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"앱이 사용자 사전에 저장하고 있는 모든 단어, 이름, 문구 등을 읽을 수 있도록 허용합니다."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"사용자 정의 사전에 단어 추가"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"앱이 사용자 사전에 새 단어를 입력할 수 있도록 허용합니다."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB 저장소의 콘텐츠 읽기"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD 카드의 콘텐츠 읽기"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"앱이 USB 저장소의 콘텐츠를 읽을 수 있도록 허용합니다."</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 7076ee0..5965ccc 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,14 +332,12 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"бул түзмөктүн жайгашкан жерине кирүү"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Сиздин социалдык маалыматыңыз"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Сиздин байланыштарыңыз жана социалдык байланыштарыңыз тууралуу маалыматтарга түз жетки алуу."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнбарак"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -348,18 +345,14 @@
<!-- no translation found for permgrouplab_storage (1971118770546336966) -->
<skip />
<string name="permgroupdesc_storage" msgid="637758554581589203">"түзмөгүңүздөгү сүрөттөр, медиа жана файлдарга кирүү"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Колдонуучунун сөздүгү"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Колдонуучунун сөздүгүндөгү сөздөрдү окуу же жазуу"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Бүктөмөлөр жана тарых"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Бүктөмөлөргө же серепчи тарыхына түз жетки алуу."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио жаздыруу"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"сүрөт тартуу жана видео жаздыруу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"телефон чалуу жана аларды башкаруу"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлор"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"олуттуу белгилериңиз жана физикалык аракетиңиз тууралуу маалыматка кирүү"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Дене сенсорлору"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"өмүр белгилериңиз тууралуу сенсордун дайындарына мүмкүнчүлүк алуу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмунун алуу"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Сиз иштеп жаткан терезенин мазмунун изилдөө."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Сыйпалап изилдөөнү жандыруу"</string>
@@ -450,16 +443,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Колдонмого планшетиңиздин чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Колдонмого сыналгыңыздын чалуулар таржымалын, ошондой эле келүүчү жана чыгуучу чалуулар тууралуу дайындарды өзгөртүү мүмкүнчүлүгү берилет. Зыянкеч колдонмолор ушуну менен чалуулар таржымалыңызды жок кылып же өзгөртүп коюшу мүмкүн."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Колдонмого телефонуңуздун чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"сиздин байланыш картаңызды окуу"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Колдонмого түзмөгүңүздө сакталган сиздин атыңыз жана байланыш маалыматтарыңыз сыяктуу персоналдык профайл маалыматтарын окуганга уруксат берет. Бул колдонмо сизди аныктай алат жана сиздин профайл маалыматтарыңызды башкаларга жөнөткөнгө жөндөмдүү билдирет."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"сиздин байланыш картаңызды өзгөртүү"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Колдонмого түзмөгүңүздө сакталган, сиздин атыңыз жана байланыш маалыматтарыңыз сыяктуу жеке профайл маалыматтарын өзгөртүү же кошуу уруксатын берет. Бул колдонмо сизди аныктай алат жана сиздин профилдик маалыматтарыңызды башкаларга жөнөтүүгө жөндөм алат дегенди билдирет."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"дене-бой сенсорлору (жүрөктүн кагышын өлчөгүчтөр сыяктуу)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Колдонмого жүрөгүңүздүн согушу сыяктуу дене-бой абалыңызды көзөмөлдөгөн сенсорлордогу дайындарды көрүп туруу мүмкүнчүлүгүн берет."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"сиздин социалдык агымыңызды окуу"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Колдонмого социалдык түйүндөргө жетүү жана сиздин жана досторуңуздун жаңыртуулары менен синхрондошуу уруксатын берет. Маалымат бөлүшкөндө абайлаңыз -- бул колдонмого сиздин социалдык түйүндөрдөгү досторуңуз менен баарлашууңузду, анын конфиденциалдуулугуна карабастан, окуганга уруксат берет. Эскертүү: бул уруксат айрым социалдык түйүндөрдө иштебеши мүмкүн."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"сиздин социалдык агымыңызга жазуу"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Колдонмого социалдык түйүндөрдөгү досторуңуздардан келген жаңыртууларды көрсөтүү мүмкүнчүлүгүн берет. Маалымат бөлүшкөндө абайлаңыз -- бул колдонмого досуңуздан келген сыяктуу көрүнгөн билдирүүлөрдү жаратууга жол берет. Эскертүү: бул уруксат айрым социалдык түйүндөрдө иштебеши мүмкүн."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"күнбарак иш-аракеттерин жана купуя маалыматтарды окуу"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Колдонмого планшетиңизде сакталган сиздин, досторуңуздун жана кесиптештериңиздин күнбарак окуяларын окуганга уруксат берет. Бул колдонмого күнбарак берилиштерин, алардын купуялуулугана жана маанилүүлүгөн карабастан бөлүшүү же сактоо уруксатын берет."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Колдонмого сыналгыңызда сакталган бардык жылнаама окуяларын, ошондой эле досторуңуз же кесиптештериңиздин окуяларын окуу мүмкүнчүлүгүн берет. Ушуну менен, колдонмо купуялуулук же астейдил мамилени талап кылуу шартына карабастан, жылнаама дайындарыңызды бөлүшүп же сактай алышы мүмкүн."</string>
@@ -587,10 +572,6 @@
<!-- no translation found for permlab_readSyncStats (7396577451360202448) -->
<skip />
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Колдонмого эсептин статистикасын, синхрондоштуруу тарыхын, анын ичинде, канча берилиштер синхрондошкондугун окуганга уруксат берет."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"сөздүккө кошкон терминдериңизди окуу"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Колдонмого колдонуучу сөздүгүндө сакталган бардык сөздөрдү, аттарды жана фразаларды окуганга уруксат берет."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"колдонуучунун сөздүгүнө сөздөрдү кошуу"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Колдонмого колдонуучунун сөздүгүнө жаңы сөздөрдү жазуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB сактагычыңыздын мазмунун окуу"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD-картаңыздын мазмунун окуу"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Колдонмого USB сактагычыңыздын мазмунун окуу мүмкүнчүлүгүн берет."</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..0065d6d 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ສະຖານທີ່"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ເຂົ້າເຖິງທີ່ຕັ້ງອຸປະກອນນີ້"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ຂໍ້ມູນສັງຄົມຂອງທ່ານ"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ແລະການເຊື່ອມຕໍ່ທາງສັງຄົມຂອງທ່ານໂດຍກົງ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ເຂົ້າຫາປະຕິທິນຂອງທ່ານ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ສົ່ງ ແລະເບິ່ງຂໍ້ຄວາມ SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ເຂົ້າເຖິງຮູບຖ່າຍ, ສື່ ແລະໄຟລ໌ຢູ່ເທິງອຸປະກອນຂອງທ່ານ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ອ່ານ ຫຼືຂຽນຄຳສັບໃນວັດຈະນານຸກົມຜູ້ໃຊ້."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ບຸກມາກ ແລະປະຫວັດເວັບໄຊ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ເຂົ້ານຳໃຊ້ບຸກແລະປະຫວັດການທ່ອງເວັບໂດຍກົງ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ໄມໂຄຣໂຟນ"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ບັນທຶກສຽງ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ກ້ອງ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ຖ່າຍຮູບ ແລະບັນທຶກວິດີໂອ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ໂທລະສັບ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ໂທ ແລະຈັດການການໂທລະສັບ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ເຊັນເຊີ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບສັນຍານຊີບ ແລະກິດຈະກຳທາງຮ່າງກາຍຂອງທ່ານ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ເຊັນເຊີຮ່າງກາຍ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ເຂົ້າຫາຂໍ້ມູນເຊັນເຊີກ່ຽວກັບສັນຍານຊີບຂອງທ່ານ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ດຶງຂໍ້ມູນເນື້ອຫາໃນໜ້າຈໍ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ກວດກາເນື້ອຫາຂອງໜ້າຈໍທີ່ທ່ານກຳລັງມີປະຕິສຳພັນນຳ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ເປີດໃຊ້ \"ການສຳຫຼວດໂດຍສຳພັດ\""</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂບັນທຶກການໂທຂອງແທັບເລັດ ຮວມທັງຂໍ້ມູນກ່ຽວກັບການໂທອອກ ແລະໂທເຂົ້ານຳ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼືແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂບັນທຶກການໂທຂອງໂທລະພາບຂອງທ່ານ ລວມທັງຂໍ້ມູນກ່ຽວກັບການໂທອອກ ແລະໂທເຂົ້ານຳ. ແອັບທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼືແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂລາຍການການໂທໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະການໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບ ຫຼືແກ້ໄຂລາຍການການໂທຂອງທ່ານໄດ້."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ອ່ານບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ມູນໂປໄຟລ໌ສ່ວນໂຕໃນອຸປະກອນຂອງທ່ານເຊັ່ນ: ຊື່ຂອງທ່ານ ແລະຂໍ້ມູນການຕິດຕໍ່ຂອງທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯຈະສາມາດລະບຸໂຕຕົນຂອງທ່ານ ແລະສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ແກ້ໄຂບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງ ຫຼືເພີ່ມຂໍ້ມູນໃສ່ໂປຣໄຟລ໌ສ່ວນບຸກຄົນທີ່ເກັບໄວ້ໃນອຸປະກອນຂອງທ່ານ, ເຊັ່ນ: ຊື່ ແລະຂໍ້ມູນຕິດຕໍ່ທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດບົ່ງບອກໂຕທ່ານ ແລະອາດສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ເຊັນເຊີຮ່າງກາຍ (ເຊັ່ນ: ຕິດຕາມອັດຕາການເຕັ້ນຂອງຫົວໃຈ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຂໍ້ມູນຈາກເຊັນເຊີທີ່ຕິດຕາມສະພາບຮ່າງການຂອງທ່ານ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຂອງຫົວໃຈຂອງທ່ານ."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ອ່ານການອັບເດດສັງຄົມອອນລາຍຂອງທ່ານ"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງ ແລະຊິ້ງຂໍ້ມູນຂ່າວສານສັງຄົມຈາກທ່ານ ແລະໝູ່ຂອງທ່ານ. ຄວນລະມັດລະວັງໃນເວລາທີ່ແລກປ່ຽນຂໍ້ມູນ -- ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການສື່ສານລະຫວ່າງທ່ານ ກັບໝູ່ຂອງທ່ານເທິງເຄືອຂ່າຍສັງຄົມ ໂດຍບໍ່ຄຳນຶງເຖິງຄວາມລັບ. ໝາຍເຫດ: ການກຳນົດສິດນີ້ອາດບໍ່ໄດ້ບັງຄັບໃຊ້ໃນທຸກເຄືອຂ່າຍສັງຄົມ."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ຂຽນໃສ່ເຄືອຂ່າຍສັງຄົມຂອງທ່ານ"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ອະນຸຍາດໃຫ້ແອັບຯສະແດງການອັບເດດຈາກໝູ່ຂອງທ່ານ. ຄວນລະວັງໃນການແປ່ງປັນຂໍ້ມູນ. ມັນຈະໄປອະນຸຍາດໃຫ້ແອັບຯ ສ້າງຂໍ້ຄວາມທີ່ອ້າງວ່າມາຈາກໝູ່ຂອງທ່ານ. ໝາຍເຫດ: ການອະນຸຍາດອາດບໍ່ຖືກບັງຄັບ ໃນບໍລິການເຄືອຂ່າຍສັງຄອມອອນລາຍທຸກອັນ."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ອ່ານກຳນົດການໃນປະຕິທິນຮວມທັງຂໍ້ມູນຄວາມລັບ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການນັດໝາຍທັງໝົດທີ່ມີບັນທຶກໃນແທັບເລັດຂອງທ່ານ, ຮວມທັງຂອງໝູ່ ຫຼືໝູ່ທີ່ເຮັດວຽກນຳກັນໄດ້ ເຊິ່ງອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຕໍ່ ຫຼືບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ ບໍ່ວ່າຈະເປັນເລື່ອງຄວາມລັບ ຫຼືເລື່ອງລະອຽດອ່ອນແບບໃດກໍຕາມ."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ອະນຸຍາດໃຫ້ແອັບອ່ານທຸກເຫດການປະຕິທິນທີ່ເກັບໄວ້ຢູ່ໃນໂທລະພາບຂອງທ່ານ, ລວມທັງເຫດການຂອງໝູ່ ຫຼືເພື່ອນຮ່ວມງານ. ອັນນີ້ອາດຈະອະນຸຍາດໃຫ້ແອັບແຊຣ໌ ແລະບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ, ໂດຍບໍ່ຄຳນຶງເຖິງຄວາມລັບ ຫຼືຄວາມອ່ອນໄຫວ."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂການຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນສຳລັບບັນຊີ. ຍົກຕົວຢ່າງ: ມັນສາມາດໃຊ້ເພື່ອເປີດນຳໃຊ້ການຊິ້ງຂໍ້ມູນຂອງ People ແອັບຯກັບບັນຊີໃດນຶ່ງໄດ້."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນ"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນຂອງບັນຊີໃດນຶ່ງ ຮວມທັງປະຫວັດການຊິ້ງຂໍ້ມູນ ແລະຈຳນວນຂໍ້ມູນທີ່ຖືກຊິ້ງ."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ອ່ານຄຳສັບທີ່ທ່ານເພີ່ມໃສ່ວັດຈະນານຸກົມ"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ອະນຸຍາດແອັບຯອ່ານຄຳສັບ, ຊື່ ແລະປະໂຫຍກທັງໝົດທີ່ຜູ່ໃຊ້ອາດບັນທຶກໄວ້ໃນວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ເພີ່ມຄຳສັບໃສ່ວັດຈະນານຸກົມທີ່ຜູ່ໃຊ້ກຳນົດເອງ"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຄຳສັບໃໝ່ ໃສ່ວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ອ່ານເນື້ອຫາຕ່າງໆໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານ"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ອ່ານເນື້ອຫາຕ່າງໆໃນ SD Card ຂອງທ່ານ"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານເນື້ອຫາຕ່າງໆໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f5d35d3..a892bbe 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vietovė"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"galimybė pasiekti įrenginio vietovės informaciją"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Socialinė informacija"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Tiesioginė prieiga prie kontaktų ir socialinių ryšių informacijos."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendorius"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"pasiekti kalendorių"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"siųsti ir peržiūrėti SMS pranešimus"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Saugykla"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"pasiekti nuotraukas, mediją ir failus įrenginyje"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Naudotojo žodynas"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Skaityti arba rašyti žodžius naudotojo žodyne."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Žymės ir istorija"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Tiesioginė prieiga prie žymių ir naršyklės istorijos."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonas"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"įrašyti garso įrašą"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparatas"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografuoti ir filmuoti"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonas"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"skambinti ir tvarkyti telefonų skambučius"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Jutikliai"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"pasiekti informaciją apie jūsų gyvybinius ženklus ir fizinę veiklą"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kūno jutikliai"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pasiekti jutiklių duomenis apie gyvybinius ženklus"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gauti lango turinį"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tikrinti lango, su kuriuo sąveikaujate, turinį."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Įjungti „Naršyti paliečiant“"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Programai leidžiama skaityti planšetinio kompiuterio skambučių žurnalą, įskaitant duomenis apie gaunamuosius ir siunčiamuosius skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Programai leidžiama keisti TV skambučių žurnalą, įskaitant duomenis apie gaunamus ir siunčiamus skambučius. Taip kenkėjiškos programos gali ištrinti arba pakeisti skambučių žurnalą."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Programai leidžiama skaityti telefono skambučių žurnalą, įskaitant duomenis apie gaunamuosius ir siunčiamuosius skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"skaityti jūsų kontakt. kortelę"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Programai leidžiama skaityti įrenginyje saugomą asmeninę profilio informaciją, pvz., vardą, pavardę ir kontaktinę informaciją. Tai reiškia, kad programa gali nustatyti tapatybę ir siųsti profilio informaciją kitiems."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"keisti jūsų kontaktinę kortelę"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Leidžiama programai keisti įrenginyje saugomą asmeninę profilio informaciją, pvz., vardą, pavardę ir kontaktinę informaciją, arba jos pridėti. Tai reiškia, kad programa gali nustatyti tapatybę ir siųsti profilio informaciją kitiems."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kūno jut. (pvz., pulso d. t.)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Programai leidžiama pasiekti duomenis, gautus iš jutiklių, stebinčių fizinę būseną, pvz., širdies ritmą."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"skaityti socialinį srautą"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Leidžiama programai pasiekti ir sinchronizuoti viešas naujienas iš jūsų ir jūsų draugų. Būkite atidūs bendrindami informaciją – programai leidžiama skaityti korespondenciją tarp jūsų ir draugų viešuosiuose tinkluose, neatsižvelgiant į konfidencialumą. Pastaba: šis leidimas negali būti taikomas visuose viešuosiuose tinkluose."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rašyti į socialinį srautą"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Leidžiama programai rodyti viešas naujienas iš jūsų draugų. Būkite atidūs bendrindami informaciją – programai leidžiama kurti pranešimus, kurie atrodo lyg būtų siunčiami draugo. Pastaba: šis leidimas negali būti taikomas visuose viešuosiuose tinkluose."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"nuskaito kalendoriaus įvykius ir konfidencialią informaciją"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Leidžiama programai skaityti visus planšetiniame kompiuteryje išsaugotus kalendoriaus įvykius, įskaitant draugų ar bendradarbių įvykius. Dėl to programai gali būti leidžiama bendrinti ar saugoti kalendoriaus duomenis, neatsižvelgiant į konfidencialumą ar privatumą."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Programai leidžiama nuskaityti visus TV saugomus kalendoriaus įvykius, įskaitant draugų ir bendradarbių. Tai pasirinkus programai gali būti leidžiama bendrinti arba išsaugoti kalendoriaus duomenis, neatsižvelgiant į tai, kad informacija gali būti konfidenciali arba neskelbtina."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Leidžiama programai keisti sinchronizuotus paskyros nustatymus. Pvz., tai gali būti naudojama norint įgalinti Žmonių programos sinchronizavimą su paskyra."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"skaityti sinchronizavimo statistiką"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Leidžiama programai skaityti sinchronizuotą paskyros statistiką, įskaitant sinchronizuotų įvykių istoriją ir informaciją, kiek duomenų sinchronizuota."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"skaityti terminus, kuriuos pridėjote į žodyną"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Leidžiama programai skaityti visus žodžius, vardus ir frazes, kuriuos naudotojas išsaugojo naudotojo žodyne."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"pridėti žodžių prie naudotojo apibrėžto žodyno"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Leidžiama programai rašyti naujus žodžius į naudotojo žodyną."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"skaityti USB atminties turinį"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"skaityti SD kortelės turinį"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Leidžiama skait. USB atmintį."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9e4cd5f..75c015b 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,32 +225,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Atrašanās vieta"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"piekļūt ierīces atrašanās vietas informācijai"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Jūsu sociālo tīklu informācija"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Tieša piekļuve informācijai par jūsu kontaktpersonām un sociālajiem savienojumiem."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendārs"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"piekļūt jūsu kalendāram"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Īsziņas"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"sūtīt un skatīt īsziņas"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Krātuve"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"piekļūt fotoattēliem, multividei un failiem jūsu ierīcē"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Lietotāja vārdnīca"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lasīt vai rakstīt vārdus lietotāja vārdnīcā."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Grāmatzīmes un vēsture"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Tieša piekļuve grāmatzīmēm un pārlūkprogrammas vēsturei."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofons"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ierakstīt audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"uzņemt attēlus un ierakstīt videoklipus"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Tālrunis"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"veikt un pārvaldīt tālruņa zvanus"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"piekļūt informācijai par jūsu dzīvības funkcijām un fizisko aktivitāti"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Ķermeņa sensori"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"piekļūt sensoru datiem par jūsu veselības rādījumiem"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Izgūt loga saturu."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Skatīt tā loga saturu, ar kuru mijiedarbojaties."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizēt funkciju “Pārlūkot pieskaroties”."</string>
@@ -334,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ļauj lietotnei pārveidot planšetdatora zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ļauj lietotnei pārveidot televizora zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu zvanu žurnālu."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ļauj lietotnei pārveidot tālruņa zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lasīt manu vizītkarti"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ļauj lietotnei lasīt ierīcē saglabāto personīgā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju. Tas nozīmē, ka lietotne var jūs identificēt un var nosūtīt jūsu profila informāciju citām personām."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"mainīt manu vizītkarti"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ļauj lietotnei mainīt ierīcē saglabāto personīgā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju, vai pievienot tai citu informāciju. Tas nozīmē, ka lietotne var jūs identificēt un var nosūtīt jūsu profila informāciju citām personām."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ķermeņa sensori (piemēram, sirdsdarbības monitori)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ļauj lietotnei piekļūt to sensoru datiem, kuri pārrauga jūsu fizisko stāvokli (piemēram, sirdsdarbības ātrumu)."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lasīt jūsu soc. tīklu straumi"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ļauj lietotnei piekļūt sociālajiem atjauninājumiem no jums un jūsu draugiem un sinhronizēt tos. Esiet piesardzīgs, kad kopīgojat informāciju, — šādi lietotne var lasīt sociālajos tīklos ar draugiem veikto saziņu, neraugoties uz konfidencialitāti. Piezīme: šo atļauju nedrīkst piemērot visiem sociālajiem tīkliem."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rakstīt sociālo tīklu straumē"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Ļauj lietotnei parādīt jūsu draugu atjauninājumus sociālajos tīklos. Esiet piesardzīgs, kad kopīgojat informāciju, — šādi lietotne var veidot ziņojumus, kas šķietami saņemti no drauga. Piezīme: šo atļauju nevar piemērot visiem sociālajiem tīkliem."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lasīt kalendāra pasākumus un konfidenciālu informāciju"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ļauj lietotnei lasīt visus planšetdatorā saglabātos kalendāra notikumus, tostarp draugu vai kolēģu notikumus. Tas var ļaut lietotnei kopīgot vai saglabāt jūsu kalendāra datus, neraugoties uz to konfidencialitāti vai sensitivitāti."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ļauj lietotnei nolasīt visus kalendāra pasākumus, kas saglabāti televizorā, tostarp jūsu draugu un kolēģu pasākumus. Tādējādi lietotne var kopīgot vai saglabāt jūsu kalendāru datus, neņemot vērā konfidencialitāti vai sensitivitāti."</string>
@@ -456,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ļauj lietotnei pārveidot konta sinhronizācijas iestatījumus. Piemēram, to var izmantot, lai iespējotu lietotnes Personas sinhronizēšanu ar kontu."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lasīt sinhronizācijas statistiku"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ļauj lietotnei lasīt konta sinhronizācijas statistiku, tostarp sinhronizācijas notikumu vēsturi un sinhronizēto datu apjomu."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lasīt vārdnīcai pievienotos vārdus"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Ļauj lietotnei lasīt visus vārdus, nosaukumus un frāzes, ko lietotājs ir saglabājis lietotāja vārdnīcā."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"vārdu pievienošana lietotāja noteiktai vārdnīcai"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ļauj lietotnei rakstīt jaunus vārdus lietotāja vārdnīcā."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lasīt USB atmiņas saturu"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lasīt SD kartes saturu"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Ļauj liet. lasīt USB atm. sat."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 25d9264..d0cd9ff 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"да пристапува до локацијата на овој уред"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Тво социјални информации"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Директен пристап до информации за вашите контакти и социјални врски."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапи до календарот"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"СМС"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"испраќа и прикажува СМС-пораки"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Меморија"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"пристапува до фотографии, медиуми и датотеки на уредот"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Кориснички речник"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Читајте или пишувајте зборови во корисничкиот речник."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Обележувачи и историја"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Директен пристап до обележувачи и историја на прелистувач."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимај аудио"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Фотоапарат"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографирај и снимај видео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"повикувај и управувај со телефонски повици"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"пристапува до информации за виталните знаци и физичката активност"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Телесни сензори"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"пристапи до податоците од сензорите за виталните знаци"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Врати содржина на прозорец"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Провери ја содржината на прозорецот со кој се комуницира."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Вклучи „Истражувај со допир“"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Овозможува апликацијата да го менува дневникот на повици на вашиот таблет, вклучувајќи податоци за дојдовни и појдовни повици. Злонамерните апликации може да го искористат ова да го избришат или да го менуваат вашиот дневник на повици."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Дозволува апликацијата да го менува дневникот на повици на вашиот телевизор, вклучувајќи и податоци за дојдовните или појдовните повици. Злонамерните апликации може да го искористат ова за да го избришат или да го менуваат вашиот дневник на повици."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Овозможува апликацијата да го менува дневникот на повици на вашиот телефон, вклучувајќи податоци за дојдовни и појдовни повици. Злонамерните апликации може да го искористат ова да го избришат или да го менуваат вашиот дневник на повици."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"прочитај ја својата картичка за контакт"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Овозможува апликацијата да чита лични податоци од профил што се зачувани на вашиот уред, како што се вашето име и информации за контакт. Ова значи дека апликацијата може да идентификува и да ги испрати информациите од вашиот профил на други."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"измени ја сопствената картичка за контакт"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Овозможува апликацијата да менува или да додава информации од личниот профил што се зачувани на вашиот уред, како што се вашето име и информации за контакт. Ова значи дека апликацијата може да ве идентификува и да ги испрати информациите од вашиот профил на други."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (како монитори за срцев пулс)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Дозволува апликацијата да пристапува до податоци од сензори кои ја следат вашата физичка состојба, како на пр. отчукувањата на срцето."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читај социјални текови"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Овозможува апликацијата да пристапува и да синхронизира социјални ажурирања од вас и вашите пријатели. Бидете внимателни кога споделувате информации - ова овозможува апликацијата да ја чита комуникацијата меѓу вас и вашите пријатели на социјалните мрежи, без оглед на нејзината доверливост. Напомена: оваа дозвола не може да се наметне на сите социјални мрежи."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"пишувај на социјалните текови"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Овозможува апликацијата да прикажува социјални ажурирања од вашите пријатели. Бидете внимателни кога споделувате информации - ова овозможува апликацијата да создава пораки кои се чини дека ги испратил пријател. Напомена: оваа дозвола не може да се наметне на сите социјални мрежи."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"прочитај настани во календар и доверливи информации"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Овозможува апликацијата да ги чита сите календарски настани што се зачувани на вашиот таблет, вклучувајќи ги и оние на пријатели или соработници. Ова може да овозможи апликацијата да ги споделува или да го зачува вашите податоци од календарот, без оглед на нивната доверливост или чувствителност."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Дозволува апликацијата да ги чита сите настани во календарот складирани во вашиот телевизор, вклучувајќи ги и оние на пријателите и соработниците. Ова може да ѝ овозможи на апликацијата да ги споделува или зачувува вашите податоци од календарот, без оглед на доверливоста или чувствителноста."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Овозможува апликацијата да ги менува подесувањата за синхронизирање на сметка. На пример, ова може да се употреби да овозможи синхронизација на апликацијата „Луѓе“ со сметка."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"читај статистика за синхронизација"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Овозможува апликацијата да ја чита статистиката за синхронизација на сметка, вклучувајќи ја и историјата на синхронизирани настани и колку податоци се синхронизирани."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"прочитај ги термините кои ги додаде во речникот"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Овозможува апликацијата да ги чита сите зборови, имиња и фрази кои корисникот можеби ги зачувал во речникот на корисникот."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"додај зборови во речник дефиниран од корисникот"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дозволува апликацијата да напише нови зборови во корисничкиот речник."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"прочитај ги содржините на твојата УСБ меморија"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"прочитај ги содржините на твојата СД картичка"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Овозможува апликацијата да ги чита содржините од вашето УСБ."</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 7b73a48..2eb442d 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ലൊക്കേഷൻ"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"നിങ്ങളുടെ സോഷ്യൽ വിവരം"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"നിങ്ങളുടെ കോൺടാക്റ്റുകളേയും സോഷ്യൽ കണക്ഷനുകളേയും സംബന്ധിച്ച വിവരങ്ങളിലേക്കുള്ള നേരിട്ടുള്ള ആക്സസ്സ്."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"കലണ്ടർ"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS സന്ദേശങ്ങൾ അയയ്ക്കുകയും കാണുകയും ചെയ്യുക"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"സംഭരണം"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഫോട്ടോകളും മീഡിയയും ഫയലുകളും ആക്സസ് ചെയ്യുക"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"ഉപയോക്തൃ നിഘണ്ടു"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ഉപയോക്തൃ നിഘണ്ടുവിലെ പദങ്ങൾ വായിക്കുകയോ എഴുതുകയോ ചെയ്യുക."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ബുക്ക്മാർക്കുകളും ചരിത്രവും"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ബുക്ക്മാർക്കുകളിലേക്കും ബ്രൗസർ ചരിത്രത്തിലേക്കുമുള്ള നേരിട്ടുള്ള ആക്സസ്സ്."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"മൈക്രോഫോണ്"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ക്യാമറ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ചിത്രങ്ങളെടുത്ത് വീഡിയോ റെക്കോർഡുചെയ്യുക"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ഫോണ്"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ഫോൺ വിളിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"സെൻസറുകൾ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെയും ശാരീരിക പ്രവർത്തനത്തെയും കുറിച്ചുള്ള വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെ കുറിച്ചുള്ള സെൻസർ വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"വിൻഡോ ഉള്ളടക്കം വീണ്ടെടുക്കുക"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"സ്പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക ഓൺ ചെയ്യുക"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടുന്ന, നിങ്ങളുടെ ടാബ്ലെറ്റിന്റെ കോൾ ലോഗ് പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്ക്കാനോ പരിഷ്ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള വിവരമുൾപ്പെടുന്ന, നിങ്ങളുടെ ടിവിയുടെ കോൾ ലോഗ് പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ദോഷകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്ക്കാനോ പരിഷ്ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടുന്ന, നിങ്ങളുടെ ഫോണിന്റെ കോൾ ലോഗ് പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്ക്കാനോ പരിഷ്ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"നിങ്ങളുടെ സ്വന്തം കോൺടാക്റ്റ് കാർഡ് റീഡുചെയ്യുക"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"നിങ്ങളുടെ പേരും ബന്ധപ്പെടാനുള്ള വിവരവും പോലുള്ള, നിങ്ങളുടെ ഉപകരണത്തിൽ സംഭരിച്ചിരിക്കുന്ന വ്യക്തിഗത പ്രൊഫൈൽ വിവരം റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളെ തിരിച്ചറിയാനും നിങ്ങളുടെ പ്രൊഫൈൽ വിവരം മറ്റുള്ളവർക്ക് അയയ്ക്കാനും അപ്ലിക്കേഷന് കഴിഞ്ഞേക്കാമെന്നാണ് ഇതിനർത്ഥം."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"നിങ്ങളുടെ സ്വന്തം കോൺടാക്റ്റ് കാർഡ് പരിഷ്ക്കരിക്കുക"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"നിങ്ങളുടെ ഉപകരണത്തിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ പേരും ബന്ധപ്പെടാനുള്ള വിവരങ്ങളും പോലുള്ള വ്യക്തിഗത പ്രൊഫൈൽ വിവരം മാറ്റാനോ ചേർക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളെ തിരിച്ചറിയാനും നിങ്ങളുടെ പ്രൊഫൈൽ വിവരം മറ്റുള്ളവർക്ക് അയയ്ക്കാനും അപ്ലിക്കേഷന് കഴിഞ്ഞേക്കാമെന്നാണ് ഇതിനർത്ഥം."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ശാരീര സെൻസറുകൾ (ഹൃദയമിടിപ്പ് നിരക്ക് മോണിറ്ററുകൾ പോലെ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"നിങ്ങളുടെ ഹൃദയമിടിപ്പ് പോലുള്ള ശാരീരികാവസ്ഥ നിരീക്ഷിക്കാൻ സെൻസറുകളിൽ നിന്ന് വിവരം ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"നിങ്ങളുടെ സോഷ്യൽ സ്ട്രീം വായിക്കുക"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"നിങ്ങളിൽ നിന്നും സുഹൃത്തുക്കളിൽ നിന്നും സോഷ്യൽ അപ്ഡേറ്റുകൾ ആക്സസ്സുചെയ്യാനും സമന്വയിപ്പിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. വിവരം പങ്കിടുമ്പോൾ ജാഗ്രത പാലിക്കുക -- ഇത് സോഷ്യൽ നെറ്റ്വർക്കുകളിൽ നിങ്ങൾക്കും സുഹൃത്തുക്കൾക്കും ഇടയിലുള്ള ആശയവിനിമയങ്ങൾ രഹസ്യാത്മകത പരിഗണിക്കാതെ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ശ്രദ്ധിക്കുക: ഈ അനുമതി എല്ലാ സോഷ്യൽ നെറ്റ്വർക്കുകളിലും നടപ്പിലാക്കാനിടയില്ല."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"നിങ്ങളുടെ സോഷ്യൽ സ്ട്രീമിലേക്ക് എഴുതുക"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"നിങ്ങളുടെ സുഹൃത്തുക്കളിൽ നിന്നുള്ള സോഷ്യൽ അപ്ഡേറ്റുകൾ പ്രദർശിപ്പിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. വിവരം പങ്കിടുമ്പോൾ ജാഗ്രത പാലിക്കുക -- ഒരു സുഹൃത്ത് അയച്ചതായി തോന്നുന്ന സന്ദേശങ്ങൾ നിർമ്മിക്കാൻ അപ്ലിക്കേഷനുകളെ ഇത് അനുവദിക്കുന്നു. ശ്രദ്ധിക്കുക: എല്ലാ സോഷ്യൽ നെറ്റ്വർക്കുകളിലും ഈ അനുമതി നടപ്പിലാക്കണമെന്നില്ല."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"കലണ്ടർ ഇവന്റുകളും രഹസ്യാത്മക വിവരവും വായിക്കുക"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"നിങ്ങളുടെ ടാബ്ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന സുഹൃത്തുക്കളുടെയോ സഹപ്രവർത്തകരുടെയോ ഉൾപ്പെടെ, എല്ലാ കലണ്ടർ ഇവന്റുകളും റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് രഹസ്യാത്മകമാണെന്നോ തന്ത്രപ്രധാനമാണെന്നോ പരിഗണിക്കാതെ നിങ്ങളുടെ കലണ്ടർ ഡാറ്റ പങ്കിടാനോ സംരക്ഷിക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"സുഹൃത്തുക്കളുടെതോ സഹപ്രവർത്തകരുടെതോ ഉൾപ്പെടെ നിങ്ങളുടെ ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും റീഡുചെയ്യുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് രഹസ്യാത്മകമോ സെൻസിറ്റിവിറ്റിയല്ലാത്തതോ ആയ കലണ്ടർ വിവരം പങ്കിടുന്നതിനോ സംരക്ഷിക്കുന്നതിനോ അപ്ലിക്കേഷനെ അനുവദിച്ചേക്കാം."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ഒരു അക്കൗണ്ടിനായി സമന്വയ ക്രമീകരണങ്ങൾ പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഉദാഹരണത്തിന്, ആളുകൾ അപ്ലിക്കേഷൻ ഒരു അക്കൗണ്ടിൽ സമന്വയിപ്പിക്കുന്നത് പ്രവർത്തനക്ഷമമാക്കാൻ ഇത് ഉപയോഗിക്കാം."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"സമന്വയ സ്ഥിതിവിവരണക്കണക്കുകൾ വായിക്കുക"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"സമന്വയ ഇവന്റുകളുടെ ചരിത്രവും ഡാറ്റ എത്രത്തോളം സമന്വയിപ്പിച്ചുവെന്നതും ഉൾപ്പെടെ, ഒരു അക്കൗണ്ടിനായി സമന്വയ സ്ഥിതിവിവരക്കണക്കുകൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"നിഘണ്ടുവിൽ നിങ്ങൾ ചേർത്ത പദങ്ങൾ വായിക്കുക"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ഉപയോക്തൃ നിഘണ്ടുവിൽ ഉപയോക്താവ് സംഭരിച്ചിരിക്കാനിടയുള്ള എല്ലാ പദങ്ങളും പേരുകളും വാക്യങ്ങളും വായിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ഉപയോക്തൃ നിർവചിത നിഘണ്ടുവിൽ പദങ്ങൾ ചേർക്കുക"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ഉപയോക്തൃ നിഘണ്ടുവിൽ പുതിയ പദങ്ങൾ എഴുതുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"നിങ്ങളുടെ USB കാർഡ് ഉള്ളടക്കം റീഡുചെയ്യുക"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"നിങ്ങളുടെ SD കാർഡ് ഉള്ളടക്കം റീഡുചെയ്യുക"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"നിങ്ങളുടെ USB സംഭരണത്തിലെ ഉള്ളടക്കങ്ങൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
@@ -1067,7 +1049,7 @@
<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_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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 42b8902..7b14b70 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Байршил"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"энэ төхөөрөмжийн байршилд хандалт хийх"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Таны нийтийн мэдээлэл"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Таны харилцагчид болон нийтийн холбооны тухай мэдээлэлд шууд хандах."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"Хуанли руу хандах"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Мессеж"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS мессежийг илгээх, харах"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Сан"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"Tөхөөрөмж дээрх зураг, медиа болон файлд хандалт хийх"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Хэрэглэгчийн толь бичиг"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Хэрэглэгчийн толь бичигт үг унших,бичих"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Хавчуурга болон түүх"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Хавчуурга болон хөтчийн түүхрүү шууд хандах."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"дуу хураах"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камер"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"зураг авах, бичлэг хийх"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Утас"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"утасны дуудлага хийх, дуудлага удирдах"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Мэдрэгчүүд"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"тaны ерөнхий байдлыг үзүүлэх үзүүлэлт болон биеийн хүчний ноогдлын мэдээлэлд нэвтрэх"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Биеийн мэдрэгч"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны контентыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Хүрч танихыг асаах"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Апп-д орж ирсэн болон гадагш хийсэн телевизийн дуудлагын бүртгэлийг өөрчлөхийг зөвшөөрдөг. Хорлонтой апликейшнүүд үүнийг ашиглан таны дуудлагын бүртгэлийг устгах эсвэл өөрчилж болох юм."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"та өөрийн харилцагчийн картыг унших"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны утсан дээр хадгалагдсан хувийн профайл мэдээллийг унших боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"та өөрийн харилцагчийн картыг өөрчлөх"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны төхөөрөмж дээр хадгалагдсан хувийн профайл мэдээллийг солих эсвэл нэмэх боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"биеийн сенсор (зүрхний цохилт хянагч гэх мэт)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Апп-т таны зүрхний цохилт гэх мэт биеийн байдлыг хянадаг мэдрэгчдийн датанд хандалт хийх боломж олгоно."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"таны нийтийн урсгалаас унших"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Апп нь та болон таны найзуудын нийтийн шинэчлэлтэд хандах болон синк хийх боломжтой. Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д нийтийн сүлжээндэх та болон таны найзууд хоорондын холбоог нууц эсэхээс үл хамааран унших боломжтой. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Таны нийтийн урсгалруу бичих"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Апп нь таны найзуудын нийтийн шинэчлэлтийг дүрслэх боломжтой.Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д таны найзаас ирсэн мэт харагдах мессеж хийх боломжийг олгоно. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"календарийн хуваарийн нууц мэдээллийг унших"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Апп нь таны таблет дээр хадгалагдсан найзууд болон хамтран ажиллагсдын календарийн бүх хуваарийг унших боломжтой. Энэ нь апп-д таны календарийн датаг нууц эсвэл эмзэг эсэхээс нь үл хамааран хуваалцах эсвэл хадгалах боломжийг олгоно."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Апп-д таны найз, эсвэл хамтран ажиллагсдын гэх мэт таны телевиз дээр хадгалагдсан бүх хуанлийн үйл ажиллагааг уншихыг зөвшөөрдөг. Энэ нь апп-д таны хуанлийн өгөгдлийг нууцлалтай эсэхээс үл хамааран хадгалахыг зөвшөөрч болох юм."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Апп нь акаунтын синк тохиргоог өөрчлөх боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийхийг идэвхжүүлэх боломжтой."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"синк статистикийг унших"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Апп нь синк үйлдэлийн түүх болон хэр их дата синк хийгдсэн зэрэг акаунтын синк статусыг унших боломжтой."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"таны толь бичигт нэмсэн нөхцөлийг унших"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Апп нь хэрэглэгч хэрэглэгчийн толь бичигт хадгалсан бүх үгс, нэрс болон хэлцийг унших боломжтой."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"хэрэглэгчийн толь бичигт үгс нэмэх"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Апп нь хэрэглэгчийн толь бичигт шинэ үг бичих боломжтой."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"таны USB сангийн контентыг унших боломжтой"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"таны SD картны контентыг унших боломжтой"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Апп нь таны USB сангийн контентыг унших боломжтой."</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 80a1d61..2fb4f93 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"या डिव्हाइसच्या स्थानावर प्रवेश करा"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"आपली सामाजिक माहिती"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"आपले संपर्क आणि सामाजिक कनेक्शनविषयीच्या माहितीवर प्रत्यक्ष प्रवेश करेल."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"कॅलेंडर"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"आपल्या कॅलेंडरवर प्रवेश करा"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS संदेश पाठवा आणि पहा"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"संचयन"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"आपल्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्ये प्रवेश करा"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"वापरकर्ता शब्दकोश"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"वापरकर्ता शब्दकोशामध्ये शब्द वाचा किंवा लिहा."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्क आणि इतिहास"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कवर आणि ब्राउझर इतिहासावर प्रत्यक्ष प्रवेश करेल."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"मायक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडिओ रेकॉर्ड करा"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"कॅमेरा"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्रे घ्या आणि व्हिडिओ रेकॉर्ड करा"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कॉल करा आणि व्यवस्थापित करा"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सर"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"आपली महत्त्वपूर्ण चिन्हे आणि शारीरिक क्रियाकलाप याविषयी प्रवेश माहिती"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर सेन्सर"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"आपल्या महत्त्वाच्या मापनांविषयी सेन्सर डेटामध्ये प्रवेश करा"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री पुनर्प्राप्त करा"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"आपण परस्परसंवाद करीत असलेल्या विंडोची सामग्री तपासा."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, आपल्या टीव्हीचा कॉल लॉग सुधारित करण्यासाठी अॅपला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपला कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"आपले स्वतःचे संपर्क कार्ड वाचा"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"आपले नाव आणि संपर्क माहिती यासारखी, आपल्या डिव्हाइसवर संचयित केलेली वैयक्तिक प्रोफाईल माहिती वाचण्यासाठी अॅप ला अनुमती देते. म्हणजेच आपल्याला अॅप ओळखू शकतो आणि इतरांना आपली प्रोफाईल माहिती पाठवू शकतो."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"आपल्या स्वतःचे संपर्क कार्ड सुधारित करा"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"आपल्या डिव्हाइसवर संचयित केलेली वैयक्तिक माहिती बदलण्यासाठी किंवा जोडण्यासाठी अॅप ला अनुमती देते. म्हणजेच अॅप आपल्याला ओळखू शकतो आणि इतरांना आपली प्रोफाईल माहिती पाठवू शकतो."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"(हृदय गती मॉनिटरसारखे) शरीर सेन्सर"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी अॅपला अनुमती देते."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"आपला सामाजिक प्रवाह वाचा"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"आपल्याकडील आणि आपल्या मित्रांकडील सामाजिक अद्यतनांवर प्रवेश करण्यास आणि त्यांचे संकालन करण्यास अॅप ला अनुमती देते. माहिती सामायिक करताना सावधगिरी बाळगा -- हे गोपनीयतेकडे दुर्लक्ष करून, आपण आणि सामाजिक नेटवर्कवरील आपल्या मित्रांमधील संप्रेषणे वाचण्यास अॅप ला अनुमती देते. टीप: या परवानगीची अंमलबजावणी सर्व सामाजिक नेटवर्कवर होऊ शकत नाही."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"आपल्या सामाजिक प्रवाहावर लिहा"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"आपल्या मित्रांकडील सामाजिक अद्यतने प्रदर्शित करण्यासाठी अॅप ला अनुमती देते. माहिती सामायिक करताना सावधगिरी बाळगा -- हे मित्राकडून येत असल्याचे दिसू शकणारे संदेश उत्पन्न करण्यासाठी अॅप ला अनुमती देते. टीप: या परवानगीची अंमलबजावणी सर्व सामाजिक नेटवर्कवर केली जाऊ शकत नाही."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"कॅलेंडर इव्हेंट तसेच गोपनीय माहिती वाचा"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"मित्र किंवा सहकर्मींसह, आपल्या टॅब्लेटवर संचयित केलेले सर्व कॅलेंडर इव्हेंट वाचण्यासाठी अॅप ला अनुमती देते. यामुळे गोपनीयता किंवा संवेदनशीलता याकडे दुर्लक्ष करून, आपला कॅलेंडर डेटा सामायिक किंवा जतन करण्यासाठी अॅप ला अनुमती देऊ शकते."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"आपल्या टीव्हीवर संचयित केलेले सर्व कॅलेंडर इव्हेंट, या मित्रांसह किंवा सह-कर्मींसह, वाचण्याची अॅपला अनुमती देते. हे गोपनीयतेकडे किंवा संवेदनशीलतेकडे दुर्लक्ष करून, आपला कॅलेंडर डेटा सामायिक करण्यासाठी किंवा जतन करण्यासाठी अॅपला अनुमती देऊ शकते."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"खात्यासाठी संकालन सेटिंग्ज सुधारित करण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांच्या अॅप चे संकालन सक्षम करण्यासाठी वापरले जाऊ शकते."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"संकालन आकडेवारी वाचा"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"संकालन इव्हेंटचा इतिहास आणि किती डेटाचे संकालन केले आहे यासह, खात्याची संकालन स्थिती वाचण्यासाठी अॅप ला अनुमती देते."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"आपण शब्दकोशात जोडलेल्या अटी वाचा"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"वापरकर्ता शब्दकोशात वापरकर्ता संचयित करू शकतो असे सर्व शब्द, नावे आणि वाक्यांश वाचण्यासाठी अॅप ला अनुमती देते."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"वापरकर्ता-परिभाषित शब्दकोशामध्ये शब्द जोडा"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"वापरकर्ता शब्दकोशात नवीन शब्द लिहिण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"आपल्या USB संचयनाची सामग्री वाचा"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"आपल्या SD कार्डची सामग्री वाचा"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"अॅपला आपल्या USB संचयनाची सामग्री वाचण्याची अनुमती देते."</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 60685c4..5464ccc 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"akses lokasi peranti ini"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Maklumat sosial anda"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke maklumat tentang kenalan anda dan sambungan sosial."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"akses kalendar anda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"hantar dan lihat mesej SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Storan"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"akses foto, media dan fail pada peranti anda"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamus Pengguna"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Baca atau tulis perkataan dalam kamus pengguna."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Penanda halaman dan Sejarah"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke penanda halaman dan sejarah penyemak imbas."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"rakam audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ambil gambar dan rakam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"buat dan urus panggilan telefon"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Penderia"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"akses maklumat tentang tanda vital dan aktiviti fizikal anda"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"akses data penderia tentang tanda vital anda"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dapatkan kembali kandungan tetingkap"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Hidupkan Jelajah melalui Sentuhan"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Membenarkan apl untuk mengubah suai panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Membenarkan apl untuk mengubah suai log panggilan TV anda, termasuk data mengenai panggilan masuk atau keluar. Apl hasad mungkin menggunakan ini untuk memadam atau mengubah suai log panggilan anda."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Membenarkan apl untuk mengubah suai panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"baca kad kenalan anda sendiri"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Membenarkan apl membaca maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ubah suai kad kenalan sendiri"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Membenarkan apl menukar atau menambah maklumat profil peribadi yang disimpan pada peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"penderia (spt. denyut jantung)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Membenarkan apl mengakses data dari penderia yang memantau keadaan fizikal anda, seperti kadar denyutan jantung anda."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"baca aliran sosial anda"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Membenarkan apl mengakses dan menyegerakkan kemas kini sosial daripada anda dan rakan anda. Berhati-hati semasa berkongsi maklumat - ini membenarkan apl untuk membaca komunikasi di antara anda dan rakan anda pada rangkaian sosial tanpa mengira kerahsiaan. Nota: kebenaran ini tidak boleh dikuatkuasakan pada semua rangkaian sosial."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"tulis ke aliran sosial anda"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Membenarkan apl memaparkan kemas kini sosial dari rakan anda. Berhati-hati semasa berkongsi maklumat - ini membenarkan apl untuk menghasilkan mesej yang kelihatan seperti datang dari seorang rakan. Nota: kebenaran ini tidak boleh dikuatkuasakan pada semua rangkaian sosial."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalendar serta maklumat sulit"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Membenarkan apl membaca semua acara kalendar yang tersimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl untuk berkongsi atau menyimpan data kalendar anda, tanpa mengira kerahsiaan atau sensitiviti."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Membenarkan apl membaca semua acara kalendar yang disimpan pada TV anda, termasuk milik rakan atau rakan sekerja. Ini mungkin membenarkan apl berkongsi atau menyimpan data kalendar anda, tanpa mengira kerahsiaan atau sensitiviti."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Membenarkan apl mengubah suai tetapan segerak untuk akaun. Sebagai contoh, ini boleh digunakan untuk mendayakan penyegerakan apl Orang dengan akaun."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"baca statistik penyegerakan"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Membenarkan apl untuk membaca statistik segerak untuk akaun, termasuk sejarah acara segerak dan berapa banyak data disegerakkan."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"baca istilah yang anda tambahkan kepada kamus"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Membenarkan apl membaca semua perkataan, nama dan frasa yang mungkin telah disimpan oleh pengguna dalam kamus pengguna."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"tambah perkataan ke kamus ditakrifkan pengguna"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Membenarkan apl menulis perkataan baharu ke dalam kamus pengguna."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"baca kandungan storan USB anda"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"baca kandungan kad SD anda"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Membenarkan aplikasi membaca kandungan storan USB anda."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 3885d976..183ba30 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"တည်နေရာ"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"စက်ပစ္စည်း၏ တည်နေရာကို အသုံးပြုမည်"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"သင်၏ ဆိုရှယ် သတင်းအချက်အလက်"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"သင်၏ အဆက်အသွယ်များနှင့် ဆိုရှယ်လ် အဆက်အသွယ်များအား၏ သတင်းအချက်အလက်များအား တိုက်ရိုက်အသုံးပြုခွင့် ရယူရန်"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"စာတိုစနစ်"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"သိုလှောင်မှုများ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များအား ဝင်သုံးပါ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"သုံးစွဲသူ အဘိဓာန်"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"သုံးစွဲသူ အဘိဓာန်တွင် စာလုံးများ ဖတ်ရန် သို့မဟုတ် ရေးရန်"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"မှတ်တမ်း နှင့် အမှတ်အသား နေရာများ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ဘရောင်ဇာ မှတ်တမ်း နှင့် အမှတ်နေရာများအား တိုက်ရိုက် ရယူရန်"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"မိုက်ခရိုဖုန်း"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"အသံဖမ်းခြင်း"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ကင်မရာ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ဓာတ်ပုံ ရိုက်ပြီးနောက် ဗွီဒီယို မှတ်တမ်းတင်ရန်"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ဖုန်း"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"အာရုံခံကိရိယာများ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"သင်၏ အဓိကကျသောလက္ခဏာများနှင့် ရုပ်ပိုင်းဆိုင်ရာဆောင်ရွက်ချက်များအကြောင်း အချက်အလက်အား ဝင်ရောက်သုံးပါ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ခန္ဓာကိုယ် အာရုံခံကိရိယာများ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"သင်၏ အဓိကကျသော လက္ခဏာများအကြောင်း အာရုံခံကိရိယာဒေတာကို ရယူသုံးစွဲရန်"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ဝင်းဒိုးမှာပါရှိသည်များကို ထုတ်ယူခြင်း"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"သင် အပြန်အလှန်လုပ်နေသော ဝင်းဒိုးမှာပါရှိသည်များကို သေချာစွာ ကြည့်ရှုစစ်ဆေးပါ"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ထိတို့ခြင်းဖြင့် ရှာဖွေပေးနိုင်တာကို ဖွင့်လိုက်ပါ"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"အပလီကေးရှင်းအား သင့်တက်ဘလက်၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်း (အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ) ကို ပြင်ဆင်ခွင့် ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ အပါအဝင်၊ သင့်တီဗွီ၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို အပလီကေးရှင်းအား ပြင်ဆင်ခွင့်ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်၏။"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"အပလီကေးရှင်းအား သင့်ဖုန်း၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်း (အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ) ကို ပြင်ဆင်ခွင့် ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"သင့်ရဲ့ အဆက်အသွယ် ကဒ် အား ဖတ်ခြင်း"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"အပလီကေးရှင်းအား စက်မှာ သိမ်းထားသော သင့်နာမည် နှင့် အဆက်အသွယ် သတင်းအချက်အလက်များကဲ့သို့သော ကိုယ်ရေးကိုယ်တာ အချက်အလက်များအား ဖတ်ခွင့် ပြုခြင်း။ အပလီကေးရှင်းမှ သင့်အား သိရှိနိုင်ပြီး သင့်ကိုယ်ရေးအချက်အလက်များအား အခြားသူများကို ပေးပို့နိုင်ပါသည်"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"သင့်ရဲ့ အဆက်အသွယ်ကဒ် အား ပြင်ရန်"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"အပလီကေးရှင်းအား စက်မှာ သိမ်းထားသော သင့်နာမည် နှင့် အဆက်အသွယ် သတင်းအချက်အလက်များကဲ့သို့သော ကိုယ်ရေးကိုယ်တာ အချက်အလက်များအား ပြင်ဆင်ခွင့် သို့ ထည့်ခွင့် ပြုခြင်း။ အပလီကေးရှင်းမှ သင့်အား သိရှိနိုင်ပြီး သင့်ကိုယ်ရေးအချက်အလက်များအား အခြားသူများကို ပေးပို့နိုင်ပါသည်"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ခန္ဓာကိုယ် အာရံခံကိရိယာများ (နှလုံးခုန်နှုန်း စောင့်ကြည့်စက် လို)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"သင်၏ နှလုံးခုန်နှုန်းလို ရုပ်ပိုင်း အခြေအနေကို စောင့်ကြပ်သည့် အာရုံခံစက်များထံမှ ဒေတာများကို appအား ရယူသုံးခွင့် ပြုပါ။"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"အပလီကေးရှင်းအား သင်နှင့် သင့်သူငယ်ချင်းတို့၏ ဆိုရှယ်နက်ဝဘ်မှ နောက်ဆုံးပေါ် အချက်အလက်များအား အသုံးပြုခွင့်နင့် ထပ်တူညီအောင် လုပ်ဆောင်ခွင့် ပြုပါ။ သတင်းအချက်အလက် မျှဝေခြင်းတွင် သတိပြုရန် -- ဤသို့ ခွင့်ပြုခြင်းဖြင့် အပလီကေးရှင်းမှ ယုံကြည်စိတ်ချရမှုကို ဂရုမပြုပဲ သင် နှင့် သူငယ်ချင်းများကြား ဆက်သွယ်မှုများအား သိရှိနိုင်ပါသည်။ မှတ်ချက်။ ဤခွင့်ပြုချက်အား ဆိုရှယ်နက်ဝဘ် အားလုံးတွင် ခွင့်ပြုခြင်း မလုပ်သင့်ပါ။"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"အပလီကေးရှင်းအား သူငယ်ချင်းများရဲ့ ဆိုရှယ်နက်ဝဘ်မှနောက်ဆုံးပေါ် အချက်အလက်များအား ဖန်သားပြင်ပေါ်တွင် ပြခွင့်ပြုရန်။ သတင်းအချက်အလက် မျှဝေခြင်းတွင် သတိပြုရန် -- ဤသို့ ခွင့်ပြုခြင်းဖြင့် အပလီကေးရှင်းမှ သူငယ်ချင်းများထံမှ လာသကဲ့သို့ သတင်းများ ပြုလုပ်နိုင်ပါသည်။ မှတ်ချက်၊ ဤခွင့်ပြုချက်အား ဆိုရှယ်နက်ဝဘ် အားလုံးတွင် ခွင့်ပြုခြင်း မလုပ်သင့်ပါ။"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ပြက္ခဒိန်အဖြစ်အပျက်များနှင့် လှို့ဝှက်အချက်အလက်များအား ဖတ်ခြင်း"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"အပလီကေးရှင်းအား တက်ဘလက်ထဲတွင် သိမ်းထားသော သူငယ်ချင်းနှင့် လုပ်ဖော်ကိုင်ဘက်များ၏ ပြက္ခဒိန် အဖြစ်အပျက်များအပါအဝင် အားလုံးကို ဖတ်ရှုခွင့်ပြုပါ။ ဒီခွင့်ပြုချက်ကြောင့် အပလီကေးရှင်းမှ ပြက္ခဒိန် အဖြစ်အပျက်များအား လျှို့ဝှက်မှု သို့ ဂရုပြုမှု ကို ထည့်သွင်းမစဉ်းစားပဲ သိမ်းဆည်းခြင်း၊ မျှဝေခြင်း ပြုလုပ်စေနိုင်ပါသည်"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ ဖြစ်ရပ်များ အပါအဝင်၊ သင့် တီဗွီတွင် သိမ်းထားသော ပြက္ခဒိန်ရှိ ဖြစ်ရပ်များအား ဖတ်ရန် app အား ခွင့်ပြုပါ။ ဤနည်းဖြင့် ယုံကြည်စိတ်ချရမှု သို့မဟုတ် ထိခိုက်လွယ်မှုတို့နှင့် မသက်ဆိုင်ဘဲ၊ သင့် ပြက္ခဒိန်ရှိ ဒေတာကို ဝေမျှရန် သို့မဟုတ် သိမ်းဆည်းရန် app အား ခွင့်ပြုသည်။"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"အကောင့်တစ်ခုအတွက် ထပ်တူညီအောင်လုပ်သော ဆက်တင်များကို ပြင်ရန် အပလီကေးရှင်းကို ခွင့်ပြုရန်။ ဥပမာ People အပလီကေးရှင်း က အကောင့်တစ်ခုနှင့် ထပ်တူညီအောင် လုပ်ဆောင်ခြင်းအား ဖွင့်ရန် သုံးနိုင်သည်။"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ထပ်တူကူးခြင်း ကိန်းဂဏန်းအချက်အလက်များကို ဖတ်ခြင်း"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"အပလီကေးရှင်းအား အကောင့်တစ်ခု၏ ထပ်တူညီအောင် လုပ်ဆောင်မှု အခြေအနေ (ပြီးခဲ့သော အဖြစ်အပျက်၊ ဒေတာ ပမာဏ ပါဝင်မှု များအပါအဝင်)ကို ဖတ်ရှုခွင့် ပြုပါ။"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"အဘိဓာန်သို့ သင့် ထည့်ထားသည်များအား ဖတ်ခြင်း"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"အပလီကေးရှင်းအား အဘိဓာန်တွင် သိမ်းဆည်းထားသော စာလုံးအားလုံး၊ နာမည်များနှင့် စာစုများ ဖတ်ရှုခွင့် ပြုရန်"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"သုံးစွဲသူ၏ အဘိဓာန် ထဲသို့ စာလုံးများ ထည့်ခြင်း"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"အသုံးပြုသူ အဘိဓာန်ထဲသို့ စာလုံး အသစ်များကို ရေးခွင့် ပြုသည်။"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB သိုလှောင်မှုမှ အချက်အလက်များအား ဖတ်ခြင်း"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD ကဒ်မှ အချက်အလက်များအား ဖတ်ခြင်း"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"အပလီကေးရှင်းအား USB သိုလှောင်မှုပေါ်မှ ဒေတာများ ဖတ်ရှုခွင့်ပြုခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 77880d8..4e9e698 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"tilgang til enhetens plassering"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Den sosiale informasjonen din"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte tilgang til informasjon om kontaktene og de sosiale forbindelsene dine."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenderen"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tilgang til kalenderen din"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"sende og lese SMS-meldinger"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"få tilgang til bilder, media og filer på enheten din"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Brukerordlisten"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Les eller skriv inn ord i brukerordlisten."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bokmerkene og loggen"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte tilgang til bokmerker og nettleserloggen."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonen"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"spill inn lyd"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kameraet"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder og ta opp video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ring og administrer anrop"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"få tilgang til informasjon om livstegnene dine og den fysiske aktiviteten din"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kroppssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få tilgang til sensordata om de vitale tegnene dine"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente innhold i vinduer"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Den kontrollerer innholdet i vinduer du samhandler med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"slå på berøringsutforsking"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lar appen endre nettbrettets samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Gjør at appen kan endre TV-ens samtalelogg, herunder data om innkommende eller utgående samtaler. Skadelige apper kan bruke dette til å slette eller endre samtaleloggen."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lar appen endre telefonens samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lese ditt eget kontaktkort"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Lar appen lese personlig profilinformasjon som er lagret på enheten, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"endre ditt eget kontaktkort"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lar appen endre eller legge til personlig profilinformasjon som er lagret på enheten din, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kroppssensorer (som pulsmålere)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Gir appen tilgang til data fra sensorer som overvåker den fysiske tilstanden din, for eksempel hjertefrekvensen din."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lese din sosiale strøm"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lar appen lese og synkronisere sosiale oppdateringer fra deg selv og vennene dine. Vær forsiktig når du deler informasjon - med denne tillatelsen kan appen lese kommunikasjon mellom deg og vennene dine på sosiale nettverk, uavhengig av konfidensialitet. Vær oppmerksom på at denne tillatelsen kanskje ikke gjelder for alle sosiale nettverk."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sosiale strøm"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Lar appen vise sosiale oppdateringer fra vennene dine. Vær forsiktig når du deler informasjon - med denne tillatelsen kan appen lage meldinger som ser ut som om de kommer fra en venn. Vær oppmerksom på at denne tillatelsen kanskje ikke gjelder på alle sosiale nettverk."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lese kalenderhendelser og konfidensiell informasjon"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Lar appen lese alle kalenderaktivitetene lagret på nettbrettet ditt, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen deler eller lagrer kalenderinformasjonen din uavhengig av konfidensialitet og sensitivitet."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Gjør at appen kan lese alle kalenderaktiviteter lagret på TV-en, herunder venner eller kollegaers aktiviteter. Dette kan føre til at appen kan dele eller lagre kalenderdataene dine uavhengig av konfidensialitet og sensitivitet."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Lar appen endre synkroniseringsinnstillingene for en konto. For eksempel kan dette brukes til å synkronisere Personer-appen med en konto."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lese synkroniseringsstatistikk"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Lar appen lese synkroniseringsstatistikk for en konto, inkludert loggen over synkroniseringsaktiviteter og hvor mye data som er synkronisert."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lese ord du har lagt til i ordboken"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Lar appen lese alle ord, navn og uttrykk som brukeren har lagret i brukerordlisten."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"legge til ord i brukerdefinert ordliste"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Lar appen skrive nye ord i brukerordlisten."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"leser innholdet i USB-lagringen"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"leser innholdet i SD-kortet"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Lar appen lese innhold på USB-lagringen din."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 04dc806..c4886b1 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"यस यन्त्रको स्थान पहुँच गर्नुहोस्"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"तपाईँको सामाजिक सूचना"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"तपाईँको सम्पर्कहरू र सामाजिक जडानहरूको बारेको जानकारीमा सिधा पहुँच पुर्याउनुहोस्।"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"तपाईँको पात्रोमा पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"भण्डारण"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"तपाईँको यन्त्रमा तस्बिर, मिडिया, र फाइलहरूको पहुँच गर्नुहोस्"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"प्रयोगकर्ता शब्दकोश"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"प्रयोगकर्ता शब्दकोशमा शब्दहरू पढ्नुहोस् वा लेख्नुहोस्।"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्कहरू र इतिहास"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कहरू र ब्राउजर इतिहासमा सिधा पहुँच।"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"क्यामेरा"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"तस्बिर तथा भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सरहरू"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"तपाईँको महत्त्वपूर्ण संकेत र शारीरिक गतिविधिबारे जानकारीको पहुँच गर्नुहोस्"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"शारीरिक सेन्सर"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"तपाईँको महत्त्वपूर्ण संकेत बारेको सेन्सर डेटा पहुँच गर्नुहोस्"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"आगमन तथा बहर्गमन डेटासहित तपाईँको ट्याब्लेटको कल लगको परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईँको कल लग परिमार्जन गर्न वा मेटाउन प्रयोग गर्न सक्छन्।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"अनुप्रयोगहरूलाई अनुमति दिन्छ तपाईँको TV को कल लग, आगमन र बहिर्गमन कलका डेटा लगायत, परिमार्जन गर्न। दुस्प्रभावी अनुप्रयोगहरूले यसलाई तपाईँको कल लग मेट्न वा परिमार्जन गर्न सक्छ।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"अनुप्रयोगलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"तपाईँको आफ्नै सम्पर्क कार्ड पढ्नुहोस्"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"अनुप्रयोगलाई तपाईंको उपकरणमा भण्डारण गरिएका व्यक्तिगत प्रोफाइल जानकारी पढ्न अनुमति दिन्छ, जस्तै तपाईंको नाम र सम्पर्क जानकारी। यसको मतलब अनुप्रयोगले तपाईंलाई पहिचान गर्न सक्दछ र तपाईंको प्रोफाइल जानकारी अरूलाई पठाउन सक्दछ।"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"तपाईँको आफ्नै सम्पर्क कार्ड परिमार्जन गर्नुहोस्"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"तपाईँको उपकरणमा भण्डार भएको व्याक्तिगत प्रोफाइल जानकारी, जस्तै तपाईँको नाम वा सम्पर्क जानकारीलाई परिवर्तन गर्न वा थप्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यसको मतलब अन्य अनुप्रयोगले तपाईँलाई चिन्न सक्छन् र सायद अन्यलाई तपाईँको प्रोफाइल जानकारी पठाउन सक्छन्।"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"शरीर सेन्सर (हृदयदर मोनिटर जस्तै)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"तपाईँको हृदय गति जस्तो सेंसर बाट डेटा पहुँचको लागि अनुप्रयोग अनुमति दिन्छ जसले तपाईँको भौतिक अवस्था अनुगमन गर्छ।"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"तपाईंको सामाजिक स्ट्रिम पढ्नुहोस्"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"तपाईँ र तपाईँका साथीहरूबाट सामाजिक अपडेटलाई पहुँच र सिंक गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। जानकारी साझेदारी गर्दा सावधान रहनुहोस् -- समाजिक नेटवर्कहरूमा तपाईँ र तपाईँको साथीको बिचमा भएका संचारलाई पढ्न विश्वासनीयता बेगरै यसले अनुप्रयोगलाई अनुमति दिन्छ। नोट: यो अनुमति बलपूर्वक सबै सामाजिक नेटवर्कहरूमा सायद नगर्न सकिन्छ।"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"तपाईँको सामाजिक प्रवाहमा लेख्नुहोस्"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"अनुप्रयोगलाई तपाईंको साथीहरूबाट सामाजिक अपडेटहरू प्रदर्शन गर्न अनुमति दिन्छ। जानकारी साझेदारी गर्ने बेलामा होशियार रहनुहोस् -- यसले अनुप्रयोगलाई सन्देशहरू निर्माण गर्न अनुमति दिन्छ जुन साथीबाट आएको देखिन्छ। टिप्पणी: यो अनुमति सबै सामाजिक सञ्जालहरूमा लागू नहुन सक्दछ।"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"गोप्य जानकारी र पात्रो घटनाहरू पढ्नुहोस्"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"अनुप्रयोगलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका ती साथीहरू वा सहयोगीहरू सहितको पात्राका कार्यक्रमहरू पढ्न अनुमति दिन्छ। यसले गोपनीयता वा संवेदनशीलता बिना पनि अनुप्रयोगलाई तपाईंको पात्राका डेटा साझेदारी गर्न वा बचत गर्न अनुमति दिन्छ।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"अनुप्रयोगलाई अनुमति दिन्छ तपाईँको TV मा भण्डारण गरिएका पात्रो घटनाहरू, साथी तथा सहकर्मीहरू लगायतका पढ्न। यसले अनुप्रयोगहरूलाई तपाईँको पात्रो डेटा साझेदारी गर्न वा सुरक्षित गर्न अनुमति दिन सक्छ, गोपनीयता वा सम्वेदनशीलताको पर्वाह बिना।"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"अनुप्रयोगहरूलाई खाताको लागि सिङ्क सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति अनुप्रयोगको सिङ्क सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"सिङ्क तथ्याङ्कहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"अनुप्रयोगलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"तपाईँले शब्दकोशमा थपेका शब्दहरू पढ्नुहोस्"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"अनुप्रयोगलाई प्रयोगकर्ताले प्रयोगकर्ता शब्दकोशमा भण्डारण गरेका हुन सक्ने सबै शब्दहरू, नामहरू र पदावलीहरू पढ्न अनुमति दिन्छ।"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"प्रयोगकर्ता-परिभाषित शब्दकोशमा शब्दहरू थप्नुहोस्।"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"प्रयोगकर्ता शब्दकोशमा नयाँ शब्द लेख्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"आफ्नो USB भण्डारणको सामग्रीहरूहरु पढ्नुहोस्"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"आफ्नो SD कार्डको सामग्रीहरूहरु पढ्नुहोस्"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"अनुप्रयोगलाई तपाईंको USB भण्डारणको सामग्री पढ्न अनुमति दिन्छ।"</string>
diff --git a/core/res/res/values-night/themes_material_daynight.xml b/core/res/res/values-night/themes_material_daynight.xml
deleted file mode 100644
index b344582..0000000
--- a/core/res/res/values-night/themes_material_daynight.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?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.
--->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see themes_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-<resources>
-
- <!-- Material theme (day/night version) for activities. -->
- <style name="Theme.Material.DayNight" parent="Theme.Material" />
-
- <!-- Variant of Material.DayNight that has a solid (opaque) action bar
- with an inverse color profile. The dark action bar sharply stands out against
- the light content (when applicable). -->
- <style name="Theme.Material.DayNight.DarkActionBar" parent="Theme.Material" />
-
- <!-- Variant of Material.DayNight with no action bar. -->
- <style name="Theme.Material.DayNight.NoActionBar" parent="Theme.Material.NoActionBar" />
-
- <!-- Variant of Material.DayNight that has no title bar and fills
- the entire screen. This theme
- sets {@link android.R.attr#windowFullscreen} to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.Fullscreen" parent="Theme.Material.NoActionBar.Fullscreen" />
-
- <!-- Variant of Material.DayNight that has no title bar and fills
- the entire screen and extends into the display overscan region. This theme
- sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
- to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.Overscan" parent="Theme.Material.NoActionBar.Overscan" />
-
- <!-- Variant of Material.DayNight that has no title bar and translucent
- system decor. This theme sets {@link android.R.attr#windowTranslucentStatus} and
- {@link android.R.attr#windowTranslucentNavigation} to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.TranslucentDecor" parent="Theme.Material.NoActionBar.TranslucentDecor" />
-
- <!-- Default Material.DayNight theme for panel windows. This removes all extraneous
- window decorations, so you basically have an empty rectangle in which
- to place your content. It makes the window floating, with a transparent
- background, and turns off dimming behind the window. -->
- <style name="Theme.Material.DayNight.Panel" parent="Theme.Material.Panel" />
-
- <!-- Material theme (day/night version) for dialog windows and activities,
- which is used by the {@link android.app.Dialog} class. This changes
- the window to be floating (not fill the entire screen), and puts a
- frame around its contents. You can set this theme on an activity if
- you would like to make an activity that looks like a Dialog. -->
- <style name="Theme.Material.DayNight.Dialog" parent="Theme.Material.DayNight.BaseDialog" />
- <style name="Theme.Material.DayNight.BaseDialog" parent="Theme.Material.BaseDialog" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that has a nice minimum width for
- a regular dialog. -->
- <style name="Theme.Material.DayNight.Dialog.MinWidth" parent="Theme.Material.Dialog.MinWidth" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that does not include a title bar. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar" parent="Theme.Material.Dialog.NoActionBar" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog.NoActionBar that has a nice minimum width for
- a regular dialog. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar.MinWidth" parent="Theme.Material.Dialog.NoActionBar.MinWidth" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that has a fixed size. -->
- <style name="Theme.Material.DayNight.Dialog.FixedSize" parent="Theme.Material.Dialog.FixedSize" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog.NoActionBar that has a fixed size. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar.FixedSize" parent="Theme.Material.Dialog.NoActionBar.FixedSize" />
-
- <!-- Theme for a window that will be displayed either full-screen on
- smaller screens (small, normal) or as a dialog on larger screens
- (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge" />
-
- <!-- Theme for a window with a dark action bar that will be displayed
- either full-screen on smaller screens (small, normal) or as a dialog
- on larger screens (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" parent="Theme.Material.DialogWhenLarge" />
-
- <!-- Theme for a window without an action bar that will be displayed either full-screen
- on smaller screens (small, normal) or as a dialog on larger screens
- (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge.NoActionBar" parent="Theme.Material.DialogWhenLarge.NoActionBar" />
-
- <!-- Theme for a presentation window on a secondary display. -->
- <style name="Theme.Material.DayNight.Dialog.Presentation" parent="Theme.Material.Dialog.Presentation" />
-
- <!-- Material user theme for alert dialog windows, which is used by the
- {@link android.app.AlertDialog} class. -->
- <style name="Theme.Material.DayNight.Dialog.Alert" parent="Theme.Material.DayNight.Dialog.BaseAlert" />
- <style name="Theme.Material.DayNight.Dialog.BaseAlert" parent="Theme.Material.Dialog.BaseAlert" />
-
- <style name="Theme.Material.DayNight.SearchBar" parent="Theme.Material.SearchBar" />
- <style name="Theme.Material.DayNight.CompactMenu" parent="Theme.Material.CompactMenu" />
-
-</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 28d86c8..50cfe83 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"de locatie van dit apparaat openen"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Uw sociale informatie"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Rechtstreeks toegang krijgen tot informatie over uw contacten en sociale connecties."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot uw agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"sms\'jes verzenden en bekijken"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Opslagruimte"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"toegang tot foto\'s, media en bestanden op uw apparaat"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Gebruikerswoordenboek"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Woorden lezen of schrijven in gebruikerswoordenboek."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bladwijzers en geschiedenis"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Rechtstreeks toegang krijgen tot bladwijzers en browsergeschiedenis."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfoon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"audio opnemen"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"foto\'s maken en video opnemen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"bellen en telefoontjes beheren"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"toegang tot informatie over uw vitale functies en fysieke activiteit"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Lichaamssensoren"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over uw vitale functies"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Inhoud van vensters ophalen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee u interactie heeft."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'Verkennen via aanraking\' inschakelen"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Toestaan dat de app het gesprekkenlijst van uw tv aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"uw eigen contactkaart lezen"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Hiermee kan de app persoonlijke profielgegevens lezen die op uw apparaat zijn opgeslagen, zoals uw naam en contactgegevens. Dit betekent dat de app u kan identificeren en uw profielgegevens naar anderen kan verzenden."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"uw eigen contactkaart aanpassen"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Hiermee kan de app persoonlijke profielgegevens wijzigen of toevoegen die op uw apparaat zijn opgeslagen, zoals uw naam en contactgegevens. Dit betekent dat de app u kan identificeren en uw profielgegevens naar anderen kan verzenden."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"lichaamssensoren (zoals hartslagmeters)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die uw lichamelijke conditie controleren, zoals uw hartslag."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"uw sociale stream lezen"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Hiermee kan de app toegang krijgen tot sociale updates van u en uw vrienden en deze synchroniseren. Wees voorzichtig bij het delen van informatie: hiermee kan de app communicatie lezen tussen u en uw vrienden op sociale netwerken, ongeacht de vertrouwelijkheid. Opmerking: deze toestemming kan niet worden afgedwongen voor alle sociale netwerken."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"schrijven naar sociale streams"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Hiermee kan de app sociale updates van u en uw vrienden weergeven. Wees voorzichtig bij het delen van informatie: hiermee kan de app berichten produceren die afkomstig lijken te zijn van een vriend. Opmerking: deze toestemming kan niet worden afgedwongen voor alle sociale netwerken."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"agenda-afspraken en vertrouwelijke informatie lezen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tablet, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tv, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Hiermee kan een app de synchronisatie-instellingen aanpassen voor een account. Deze toestemming kan bijvoorbeeld worden gebruikt om synchronisatie van de app Personen in te schakelen voor een account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"synchronisatiestatistieken lezen"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Hiermee kan een app de synchronisatiestatistieken voor een account lezen, inclusief de geschiedenis van synchronisatie-activiteiten en hoeveel gegevens zijn gesynchroniseerd."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"termen lezen die u heeft toegevoegd aan het woordenboek"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Hiermee kan de app alle woorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"woorden toevoegen aan het gebruikerswoordenboek"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Hiermee kan de app nieuwe woorden schrijven naar het gebruikerswoordenboek."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"de inhoud van uw USB-opslag lezen"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"de inhoud van uw SD-kaart lezen"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"De app toestaan de inhoud van uw USB-opslag te lezen."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 8ce1a9b..cacd529 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡਿਵਾਈਸ ਦੇ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਤੱਕ ਪਹੁੰਚੋ"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ਤੁਹਾਡੀ ਸਮਾਜਿਕ ਜਾਣਕਾਰੀ"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਅਤੇ ਸਮਾਜਿਕ ਕਨੈਕਸ਼ਨਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਤੱਕ ਸਿੱਧੀ ਪਹੁੰਚ।"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਆਪਣੇ ਕੈਲੰਡਰ ਦੀ ਐਕਸੈਸ ਕਰੋ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦਿਖਾਓ"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ਸਟੋਰੇਜ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੀ ਡਿਵਾਈਸ ਤੇ ਫੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚੋ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਸ਼ਬਦ ਪੜ੍ਹੋ ਜਾਂ ਲਿਖੋ।"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ਬੁੁੱਕਮਾਰਕਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਇਤਿਹਾਸ ਤੱਕ ਸਿੱਧੀ ਪਹੁੰਚ।"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ਮਾਈਕ੍ਰੋਫੋਨ"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ਕੈਮਰਾ"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਖਿੱਚੋ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ਫੋਨ"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"ਸੰੰਵੇਦਕ"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ਆਪਣੇ ਮਹੱਤਵਪੂਰਣ ਲੱਛਣਾਂ ਅਤੇ ਸਰੀਰਕ ਗਤੀਵਿਧੀ ਬਾਰੇ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"ਸਰੀਰ ਸੰਵੇਦਕ"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਮਹੱਤਵਪੂਰਣ ਲੱਛਣਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਇੰਟਰੈਕਟ ਕਰ ਰਹੇ ਹੋ।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਚਾਲੂ ਕਰੋ"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ TV ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫੋਨ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖ਼ਰਾਬ ਐਪਸ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੇ ਹਨ।"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ਆਪਣਾ ਖੁਦ ਦਾ ਸੰਪਰਕ ਕਾਰਡ ਪੜ੍ਹੋ"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਸਟੋਰ ਕੀਤੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਵੇਂ ਤੁਹਾਡਾ ਨਾਮ ਅਤੇ ਸੰਪਰਕ ਜਾਣਕਾਰੀ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਨੂੰ ਪਛਾਣ ਸਕਦਾ ਹੈ ਅਤੇ ਹੋਰਾਂ ਨੂੰ ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ ਭੇਜ ਸਕਦਾ ਹੈ।"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ਆਪਣਾ ਖੁਦ ਦਾ ਸੰਪਰਕ ਕਾਰਡ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਸਟੋਰ ਕੀਤੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ ਬਦਲਣ ਜਾਂ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਵੇਂ ਤੁਹਾਡਾ ਨਾਮ ਅਤੇ ਸੰਪਰਕ ਜਾਣਕਾਰੀ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਨੂੰ ਪਛਾਣ ਸਕਦਾ ਹੈ ਅਤੇ ਹੋਰਾਂ ਨੂੰ ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ ਭੇਜ ਸਕਦਾ ਹੈ।"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ਸਰੀਰ ਸੰਵੇਦਕ (ਜਿਵੇਂ ਦਿਲ ਦੀ ਧੜਕਣ ਦੇ ਨਿਰੀਖਕ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ਐਪ ਨੂੰ ਉਹਨਾਂ ਸੰਵੇਦਕਾਂ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜੋ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਥਿਤੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਵੇਂ ਤੁਹਾਡੇ ਦਿਲ ਦੀ ਧੜਕਣ।"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ਆਪਣੀ ਸਮਾਜਿਕ ਸਟ੍ਰੀਮ ਪੜ੍ਹੋ"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਅਤੇ ਤੁਹਾਡੇ ਦੋਸਤਾਂ ਦੀਆਂ ਸਮਾਜਿਕ ਅਪਡੇਟਾਂ ਤੱਕ ਪਹੁੰਚ ਅਤੇ ਸਿੰਕ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਜਾਣਕਾਰੀ ਸੇਅਰ ਕਰਦੇ ਸਮੇਂ ਸਾਵਧਾਨ ਰਹੋ - ਇਹ ਸਮਾਜਿਕ ਨੈਟਵਰਕਾਂ ਤੇ ਤੁਹਾਡੇ ਅਤੇ ਤੁਹਾਡੇ ਦੋਸਤਾਂ ਵਿਚਕਾਰ ਸੰਚਾਰ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਗੁਪਤਤਾ ਤੇ ਧਿਆਨ ਦਿੱਤੇ ਬਿਨਾਂ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਸਾਰੇ ਸਮਾਜਿਕ ਨੈਟਵਰਕਾਂ ਤੇ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ਆਪਣੀ ਸਮਾਜਿਕ ਸਟ੍ਰੀਮ ਵਿੱਚ ਲਿਖੋ"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦੋਸਤਾਂ ਦੀਆਂ ਸਮਾਜਿਕ ਅਪਡੇਟਾਂ ਤੱਕ ਡਿਸਪਲੇ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਜਾਣਕਾਰੀ ਸੇਅਰ ਕਰਦੇ ਸਮੇਂ ਸਾਵਧਾਨ ਰਹੋ - ਇਹ ਐਪ ਨੂੰ ਅਜਿਹੇ ਸੁਨੇਹੇ ਉਤਪੰਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਦੋਸਤ ਤੋਂ ਆਏ ਜਾਪ ਸਕਦੇ ਹਨ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਸਾਰੇ ਸਮਾਜਿਕ ਨੈਟਵਰਕਾਂ ਤੇ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਪਲਸ ਗੁਪਤ ਜਾਣਕਾਰੀ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਤੇ ਸਟੋਰ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਦੋਸਤਾਂ ਜਾਂ ਸਹਿਯੋਗੀਆਂ ਦੀਆਂ ਇਵੈਂਟਾਂ ਸਮੇਤ। ਇਹ ਐਪ ਨੂੰ ਤੁਹਾਡਾ ਕੈਲੰਡਰ ਡਾਟਾ ਸ਼ੇਅਰ ਜਾਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ, ਗੁਪਤਤਾ ਜਾਂ ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਤੇ ਧਿਆਨ ਦਿੱਤੇ ਬਿਨਾਂ।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ TV ਤੇ ਸਟੋਰ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਦੋਸਤਾਂ ਜਾਂ ਸਹਿਯੋਗੀਆਂ ਦੀਆਂ ਇਵੈਂਟਾਂ ਸਮੇਤ। ਇਹ ਐਪ ਨੂੰ ਤੁਹਾਡਾ ਕੈਲੰਡਰ ਡਾਟਾ ਸ਼ੇਅਰ ਜਾਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ, ਗੁਪਤਤਾ ਜਾਂ ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਤੇ ਧਿਆਨ ਦਿੱਤੇ ਬਿਨਾਂ।"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸਦੀ ਵਰਤੋਂ ਇੱਕ ਖਾਤੇ ਨਾਲ People ਐਪ ਦਾ ਸਿੰਕ ਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ਸਿੰਕ ਅੰਕੜੇ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸਟੇਟਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਸਿੰਕ ਇਵੈਂਟਾਂ ਦੇ ਇਤਿਹਾਸ ਅਤੇ ਕਿੰਨਾ ਡਾਟਾ ਸਿੰਕ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਸਮੇਤ।"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ਉਹ ਸ਼ਬਦ ਪੜ੍ਹੋ ਜੋ ਤੁਸੀਂ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਜੋੜੇ ਸੀ"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ਐਪ ਨੂੰ ਉਹ ਸਾਰੇ ਸ਼ਬਦ, ਨਾਮ ਅਤੇ ਵਾਕਾਂਸ਼ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਹਨਾਂ ਨੂੰ ਉਪਭੋਗਤਾ ਨੇ ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਸਟੋਰ ਕੀਤਾ ਹੋਇਆ ਹੋ ਸਕਦਾ ਹੈ।"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ਉਪਭੋਗਤਾ-ਪਰਿਭਾਸ਼ਿਤ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਸ਼ਬਦ ਜੋੜੋ"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ਐਪ ਨੂੰ ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਨਵੇਂ ਸ਼ਬਦ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ਆਪਣੀ USB ਸਟੋਰੇਜ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹੋ"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ਆਪਣੇ SD ਕਾਰਡ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹੋ"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ਐਪ ਨੂੰ ਆਪਣੀ USB ਸਟੋਰੇਜ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 1737626..6de8f6f 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokalizacja"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"dostęp do lokalizacji tego urządzenia"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Twoje informacje społecznościowe"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Bezpośredni dostęp do informacji o Twoich kontaktach i powiązaniach społecznościowych."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendarz"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostęp do kalendarza"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"wysyłać i wyświetlać SMS-y"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Pamięć"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"uzyskiwać dostęp do zdjęć, multimediów i plików na Twoim urządzeniu"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Słownik użytkownika"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Odczytywanie lub zapisywanie słów w słowniku użytkownika."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Zakładki i historia"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Bezpośredni dostęp do zakładek i historii przeglądarki."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"nagrywanie dźwięku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Aparat"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"robienie zdjęć i nagrywanie filmów"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"nawiązywanie połączeń telefonicznych i zarządzanie nimi"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Czujniki"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"uzyskiwać dostęp do informacji o podstawowych funkcjach Twojego organizmu i Twojej aktywności fizycznej"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Czujniki na ciele"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"dostęp do danych czujnika podstawowych funkcji życiowych"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobieranie zawartości okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włączenie czytania dotykiem"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Pozwala aplikacji modyfikować rejestr połączeń telewizora, w tym dane o połączeniach przychodzących i wychodzących. Szkodliwe aplikacje mogą to wykorzystać do skasowania lub zmodyfikowania rejestru połączeń."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"odczytywanie własnej karty kontaktu"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Pozwala aplikacji na odczyt osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"zmiana własnej karty kontaktu"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pozwala aplikacji na zmianę lub dodanie osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"czujniki ciała (np. monitorujące tętno)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Pozwala aplikacji na dostęp do danych z czujników, które monitorują Twój stan fizyczny (np. tętno)."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"odczyt sieci społecznościowych"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Pozwala aplikacji na odczyt i synchronizację informacji publikowanych przez Ciebie i Twoich znajomych w sieciach społecznościowych. Zachowaj ostrożność, udostępniając informacje. Aplikacja z tym uprawnieniem może odczytać całą komunikację, którą prowadzisz ze swoimi znajomymi w sieciach społecznościowych, niezależnie od jej poufności. Uwaga: to uprawnienie może nie być egzekwowane we wszystkich sieciach społecznościowych."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapis sieci społecznościowych"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Pozwala aplikacji na wyświetlanie informacji publikowanych przez Twoich znajomych w sieciach społecznościowych. Zachowaj ostrożność, udostępniając informacje. Aplikacja z tym uprawnieniem może tworzyć wiadomości, które wyglądają jakby pochodziły od znajomych. Uwaga: to uprawnienie może nie być egzekwowane we wszystkich sieciach społecznościowych."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"odczyt wydarzeń w kalendarzu wraz z informacjami poufnymi"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Pozwala aplikacji na odczytywanie wszystkich wydarzeń w kalendarzu zapisanych na tablecie, w tym pochodzących od znajomych i współpracowników. Aplikacja z takim uprawnieniem może udostępniać i zapisywać dane kalendarza niezależnie od ich poufności."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Pozwala aplikacji odczytywać wszystkie zapisane na urządzeniu wydarzenia z kalendarza, również należące do znajomych i współpracowników. Może to umożliwić aplikacji przekazywanie lub zapisywanie danych z kalendarza, także tych poufnych."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Pozwala aplikacji na modyfikowanie ustawień synchronizacji z kontem. Tego uprawnienia można użyć np. do włączenia synchronizacji z kontem aplikacji Ludzie."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"czytanie statystyk dotyczących synchronizowania"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Pozwala aplikacji na czytanie statystyk synchronizacji konta, w tym historii zdarzeń synchronizacji oraz ilości zsynchronizowanych danych."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"odczytywanie terminów dodanych do słownika"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Pozwala aplikacji na odczytywanie wszelkich słów, nazw i wyrażeń zapisanych w słowniku użytkownika."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"dodawanie wyrazów do słownika zdefiniowanego przez użytkownika"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Pozwala aplikacji na zapisywanie nowych słów do słownika użytkownika."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"odczytywanie zawartości pamięci USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"odczytywanie zawartości karty SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Pozwala aplikacji na odczyt Twojej pamięci USB."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7ec15e3..c257e8c 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localização"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"aceder à localização do seu dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"As suas informações sociais"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acesso direto às informações sobre os seus contactos e ligações sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendário"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"aceder ao calendário"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar e ver mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"aceder a fotos, multimédia e ficheiros no dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionário do Utilizador"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escrever palavras no dicionário do utilizador."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e Histórico"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acesso direto aos marcadores e histórico do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmara"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotografias e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telemóvel"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerir chamadas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"aceder a informações acerca dos seus sinais vitais e da atividade física"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores de corpo"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"aceder a dados do sensor acerca dos seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Obter conteúdo da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo de uma janela com a qual está a interagir."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar Através do Toque"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite à aplicação modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite à aplicação modificar o registo de chamadas da sua TV, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite à aplicação modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ler o próprio cartão de contacto"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite que a aplicação leia dados de perfil pessoais guardados no dispositivo, tais como o seu nome e informações de contacto. Isto significa que outras aplicações podem identificá-lo e enviar os seus dados de perfil a terceiros."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modificar o próprio cartão de contacto"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que a aplicação altere ou adicione dados de perfil pessoais guardados no dispositivo, tais como o seu nome e informações de contacto. Isto significa que outras aplicações podem identificá-lo e enviar os seus dados de perfil a terceiros."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporais (como monitores do ritmo cardíaco)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que a aplicação aceda a dados de sensores que monitorizam a sua condição física, como o ritmo cardíaco."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler o seu fluxo social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que a aplicação aceda e sincronize atualizações de redes sociais suas e dos seus amigos. Tenha cuidado ao partilhar informações, pois esta ação permite que a aplicação leia comunicações entre si e os seus amigos nas redes sociais, independentemente do grau de confidencialidade. Nota: esta autorização pode não ser aplicada a todas as redes sociais."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever para o seu fluxo social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite que a aplicação apresente atualizações de redes sociais de amigos. Tenha cuidado ao partilhar informações, pois esta ação permite que a aplicação produza mensagens que podem parecer ser enviadas por um amigo. Nota: esta autorização pode não ser aplicada a todas as redes sociais."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ler eventos do calendário, para além de informações confidenciais"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite que a aplicação leia todos os eventos do calendário guardados no tablet, incluindo os de amigos ou colegas de trabalho. Pode permitir que a aplicação partilhe ou guarde dados do calendário, independentemente da confidencialidade ou sensibilidade."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite à aplicação ler todos os eventos de calendário armazenados na sua TV, incluindo os de amigos e de colegas de trabalho. Isto pode permitir à aplicação partilhar ou guardar os seus dados de calendário, independentemente da confidencialidade ou sensibilidade."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite que uma aplicação modifique as definições de sincronização de uma conta. Por exemplo, pode ser utilizada para ativar a sincronização da aplicação Pessoas com uma conta."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ler estatísticas de sincronização"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite que uma aplicação leia o estado de sincronização de uma conta, incluindo o histórico de eventos de sincronização e a quantidade de dados sincronizados."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ler os termos adicionados ao dicionário"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite que a aplicação leia todas as palavras, nomes e expressões que o utilizador possa ter guardado no dicionário do utilizador."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"adicionar palavras ao dicionário definido pelo utilizador"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite à aplicação escrever novas palavras no dicionário do utilizador."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ler os conteúdos da memória USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ler os conteúdos do cartão SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite que a aplicação leia conteúdos da memória USB."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a4e93ad..235f0db 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acessar o local do dispositivo"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Suas informações sociais"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acesso direto às informações de seus contatos e conexões sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"acessar sua agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar e ver mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"acessar fotos, mídia e arquivos do seu dispositivo"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionário do usuário"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escrever as palavras do dicionário do usuário."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoritos e histórico"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acesso direto aos favoritos e histórico do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerenciar chamadas telefônicas"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"acessar informações sobre seus sinais vitais e atividade física"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acessar dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite que o app modifique o registro de chamadas de seu tablet, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite que o app modifique o registro de chamadas da sua TV, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usá-lo para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite que o app modifique o registro de chamadas de seu telefone, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ler próprio cartão de contato"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite que o app leia informações de perfil pessoal armazenadas no dispositivo, como seu nome e dados de contato. Isso significa que o app poderá identificá-lo e enviar suas informações de perfil para terceiros."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"mod. próprio cartão contato"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que o app altere ou adicione informações pessoais de perfil armazenadas em seu dispositivo, como seu nome e informações de contato. Isso significa que o app pode identificá-lo e enviar as informações de seus perfil para terceiros."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporais"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que o app acesse dados de sensores que monitoram sua condição física, como a frequência cardíaca."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler suas transmissões sociais"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que o app acesse e sincronize suas atualizações sociais e as de seus amigos. Tenha cuidado ao compartilhar informações: isto permite que o app leia as mensagens trocadas por você e seus amigos em redes sociais, independentemente de sua confidencialidade. Obsservaç: pode não ser aplicável a todas as redes sociais."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever p/ suas transm. soc."</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite que o app exiba atualizações sociais de seus amigos. Tenha cuidado ao compartilhar informações: isto permite que o app produza mensagens aparentemente enviadas por amigos. Observação: pode não ser aplicável a todas as redes sociais."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"ler compromissos e informações confidenciais"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite que o app leia todos os eventos do calendário armazenados no tablet, incluindo os de amigos ou colegas de trabalho. Pode permitir que o app compartilhe ou salve os dados do calendário, independentemente de sua confidencialidade."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite que o app leia todos os eventos da agenda armazenados na sua TV, incluindo os de amigos ou colegas de trabalho. Isso pode permitir que o app compartilhe ou salve os dados da sua agenda, independentemente de serem confidenciais ou sensíveis."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite que o app modifique as configurações de sincronização de uma conta. Por exemplo, pode ser usado para ativar a sincronização do app People com uma conta."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ler estatísticas de sincronização"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite que um app acesse as estatísticas de sincronização de uma conta, incluindo a história dos eventos de sincronização e a quantidade de dados sincronizados."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ler termos adicionados ao dicionário"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite que o app leia palavras, nomes e frases armazenados pelo usuário no dicionário do usuário."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"adicionar palavras ao dicionário do usuário"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite que o app grave novas palavras no dicionário do usuário."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ler conteúdo do armaz. USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ler conteúdo do cartão SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Perm. que app leia cartão SD."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b2031c6..b0552e9c 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,32 +225,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Locație"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accesează locația acestui dispozitiv"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informaţiile dvs. sociale"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acces direct la informaţii despre persoanele de contact și conexiunile dvs. sociale."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesează calendarul"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"trimite și vede mesajele SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stocare"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accesează fotografiile, conținutul media și fișierele de pe dispozitiv"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicţionarul utilizatorului"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Citește sau scrie cuvinte în dicționarul utilizatorului."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcajele și Istoricul"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acces direct la marcaje și la istoricul navigării."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfonul"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistrează conținut audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera foto"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiază și înregistrează videoclipuri"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"inițiază și gestionează apeluri telefonice"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"accesează informații despre semnele vitale și activitatea fizică"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accesează datele înregistrate de senzori despre semnele vitale"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperează conținutul ferestrei"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
@@ -334,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite aplicației să modifice jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău-intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul de apeluri."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"citeşte cartea dvs. de vizită"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permite aplicației să citească informaţiile personale din profil stocate pe dispozitiv, cum ar fi numele și informaţiile de contact, ceea ce înseamnă că aplicația vă poate identifica și poate trimite informaţiile dvs. de profil altor utilizatori."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modifică cartea dvs. de vizită"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite aplicației să schimbe sau să adauge conţinut în informaţiile personale din profil stocate pe dispozitivul dvs., cum ar fi numele și informaţiile dvs. de contact. Aceasta înseamnă că aplicația vă poate identifica și poate trimite informaţiile din profilul dvs. altor persoane."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"senzori (ex.: senzori de ritm cardiac)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite aplicației să acceseze date de la senzorii care vă monitorizează starea fizică, cum ar fi ritmul cardiac."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"citeşte fluxul social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite aplicației să acceseze și să sincronizeze actualizările sociale de la dvs. și de la prietenii dvs. Daţi dovadă de precauţie când distribuiţi informaţii - cu această permisiune aplicația citeşte comunicările realizate între dvs. și prietenii dvs. în reţelele sociale, indiferent de gradul de confidenţialitate a acestora. Notă: această permisiune nu poate fi aplicată pentru toate reţelele sociale."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrie în fluxul social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permite aplicației să afişeze actualizări sociale de la prietenii dvs. Distribuiți cu precauţie aceste informaţii - cu această permisiune aplicația produce mesaje care pot părea că vin de la un prieten. Notă: această permisiune nu poate fi aplicată pentru toate reţelele sociale."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar și a informaţiilor confidenţiale"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite aplicației să citească toate evenimentele din calendar stocate pe tabletă, inclusiv cele ale prietenilor sau colegilor. Acest lucru poate permite aplicației să distribuie sau să salveze datele din calendar, indiferent dacă acestea sunt confidenţiale sau sensibile."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite aplicației să citească toate evenimentele din calendar stocate pe televizor, inclusiv cele ale prietenilor sau colegilor. Cu această permisiune, aplicația poate să permită accesul la datele din calendar sau să le salveze, indiferent dacă acestea sunt confidențiale sau sensibile."</string>
@@ -456,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permite unei aplicații să modifice setările de sincronizare ale unui cont. De exemplu, cu această permisiune aplicația poate activa sincronizarea aplicației Persoane cu un anumit cont."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"citire statistici privind sincronizarea"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite unei aplicații să citească statisticile de sincronizare ale unui cont, inclusiv istoricul evenimentelor de sincronizare și volumul datelor sincronizate."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"citeşte termenii adăugaţi în dicţionar"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Permite aplicației să citească toate cuvintele, numele și expresiile stocate în dicţionarul utilizatorului."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"adaugă cuvinte în dicţionarul definit de utilizator"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite aplicației să scrie cuvinte noi în dicţionarul utilizatorului."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"citeşte conţinutul stocării USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"citeşte conţinutul cardului SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite aplic. citirea conținutului stoc. USB."</string>
@@ -937,7 +919,7 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reactivaţi acest mod din Setări de sistem > Aplicaţii > Descărcate."</string>
<string name="smv_application" msgid="3307209192155442829">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o vers. superioară..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o versiune superioară..."</string>
<string name="android_start_title" msgid="8418054686415318207">"Android pornește..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Se optimizează stocarea."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Se optimizează aplicația <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 58ffa3b..a3dcf12 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,32 +226,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"доступ к данным о местоположении устройства"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Информация о моих контактах"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Прямой доступ к информации о моих контактах и социальных связях."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"доступ к календарю"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"отправка и просмотр SMS-сообщений"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Память"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"доступ к фотографиям, файлам и мультимедийному контенту на вашем устройстве"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Пользовательский словарь"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Чтение слов в пользовательском словаре или их запись."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Закладки и история"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Прямой доступ к закладкам и истории браузера."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"запись аудио"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фото- и видеосъемка"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"осуществление телефонных звонков и управление ими"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"доступ к основным показателям состояния организма и сведениям о физической активности"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"доступ к данным датчиков о состоянии организма"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Получать содержимое окна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Анализировать содержимое активного окна."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включать аудиоподсказки"</string>
@@ -335,16 +329,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Приложение сможет вносить изменения в список вызовов планшетного ПК и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Изменение списка вызовов телевизора и данных о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Приложение сможет вносить изменения в список вызовов телефона и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"Просмотр ваших контактных данных"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Приложение сможет просматривать вашу личную информацию (например, имя и контактные данные), сохраненную на устройстве. Получив эти данные, приложение сможет отправить их другим пользователям."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"Изменение ваших контактных данных"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Приложение сможет изменять вашу личную информацию (например, имя и контактные данные), сохраненную на устройстве. Получив эти данные, приложение сможет отправить их другим пользователям."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"датчики (например, пульсометр)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Приложение сможет получить доступ к данным датчиков, размещенных на теле, например измеряющих частоту сердцебиения."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Просмотр записей в вашей социальной ленте"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Приложение сможет просматривать и синхронизировать записи, публикуемые вами и вашими друзьями в социальных сетях. Будьте осторожны при передаче информации! С этим разрешением приложение сможет просматривать вашу переписку с друзьями в социальных сетях независимо от настроек конфиденциальности. Примечание. Это разрешение может применяться не во всех социальных сетях."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Добавление записей в вашу социальную ленту"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Приложение сможет отображать новости, добавленные вашими друзьями в социальных сетях. Будьте осторожны при передаче этой информации! С этим разрешением приложение сможет создавать сообщения от лица друзей. Примечание. Это разрешение может применяться не во всех социальных сетях."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"Просмотр в календаре мероприятий и конфиденциальных данных"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Приложение сможет просматривать мероприятия в календаре устройства, в том числе добавленные друзьями или коллегами, а также передавать и сохранять данные календаря независимо от настроек конфиденциальности."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Доступ к записям календаря на телевизоре, в том числе добавленным вашими друзьями и коллегами. Приложение сможет пересылать данные календаря и сохранять их независимо от параметров конфиденциальности."</string>
@@ -457,10 +443,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Приложение сможет изменять настройки синхронизации аккаунта. Например, с помощью этого разрешения можно включить в аккаунте синхронизацию контактов."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Просмотр статистики синхронизации"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Приложение сможет просматривать статистику синхронизации аккаунта, в том числе историю событий и объем синхронизированных данных."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"Просмотр добавленных в словарь слов"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Приложение получит доступ ко всем словам и фразам, которые хранятся в пользовательском словаре."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"Добавление слов в словарь пользователя"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Приложение сможет добавлять слова в пользовательский словарь."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"Просмотр данных на USB-накопителе"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"Считывание содержимого SD-карты"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Приложение сможет считывать данные на USB-накопителе."</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 58cb2ea..c406686 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ස්ථානය"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"මෙම උපාංගයේ ස්ථානය ප්රවේශ කිරීම"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ඔබගේ සමාජයීය තොරතුරු"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ඔබගේ සම්බන්ධතා සහ සාමාජ සම්බන්ධයන් ගැන තොරතුරු වෙත ඍජු ප්රවේශය."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"කෙටි පණිවිඩ"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ආචයනය"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ඔබේ උපාංගයේ ඇති ඡායාරූප, මාධ්ය සහ ගොනුවලට පිවිසීම"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"පරිශීලක ශබ්ද කෝෂය"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"පරිශීලක ශබ්ද කෝෂයේ වචන කියවීම සහ ලිවිම."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"පිටුසන් සහ ඉතිහාසය"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"පිටුසන් සහ බ්රව්සර ඉතිහාසය වෙත ඍජු ප්රවේශය."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"මයික්රොෆෝනය"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ශ්රව්ය පටිගත කරන්න"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"කැමරාව"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"පින්තූර ගැනීම සහ වීඩියෝ පටිගත කිරීම"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"දුරකථනය"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"දුරකථන ඇමතුම් සිදු කිරීම සහ කළමනාකරණය කිරීම"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"සංවේදක"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"ඔබේ ජෛව ලක්ෂණ සහ ශාරීරික ක්රියාකාරකම් පිළිබඳ ප්රවේශ තොරතුරු"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ඔබේ ජෛව ලක්ෂණ පිළිබඳ සංවේදක දත්ත වෙත පිවිසෙන්න"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"කවුළු අන්න්තර්ගතය ලබාගන්න"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ඔබ අන්තර්ක්රියාකාරී වන කවුළුවේ අන්තර්ගතය පරීක්ෂා කරන්න."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ස්පර්ශයෙන් ගවේෂණය සක්රිය කරන්න"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිතා කෙරේ."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිතා කෙරේ."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"පැමිණෙන සහ පිටවෙන ඇමතුම් දත්ත ඇතුළුව ඔබගේ දුරකථනයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කල හැක."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"ඔබගේ සම්බන්ධතා පත කියවන්න"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ඔබගේ නම සම්බන්ධතා තොරතුරු ආදී ඔබගේ උපාංගයේ ගබඩා වී ඇති පුද්ගලික පැතිකඩ තොරතුරු කියවීමට යෙදුමට අවසර දෙන්න. මෙහි තේරුම යෙදුමට ඔබව හඳුනා ගැනීමට හැකි වන බව සහ ඔබගේ පුද්ගලික තොරතුරු අනෙක් අයට යැවීමට ද හැකි වීමයි."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ඔබගේ සම්බන්ධතා පත වෙනස් කිරීම"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ඔබගේ නම සහ සම්බන්ධතා තොරතුරු වැනි ඔබගේ උපාංගයේ ආචයනය කරන ලද පුද්ගලික පැතිකඩ තොරතුරු වෙනස් කිරීමට හෝ එකතු කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් යෙදුමට ඔබව හඳුනා ගත හැකි අතර අනෙක් අයට ඔබගේ පැතිකඩ තොරතුරු යැවිය හැකි බව කියවෙයි."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"සිරුර සංවේදකයන් (හෘද ස්පන්දන වේගය නිරීක්ෂණය කිරීම වැනි)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"හෘද ස්පන්දන වේගය වැනි ඔබගේ ශාරීරික තත්ත්වය නිරීක්ෂණය කරන සංවේදක වලින් දත්ත ලබාගැනීමට යෙදුමට ඉඩ දෙන්න."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ඔබගේ සමාජ ප්රවාහය කියවන්න"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ඔබගේ සහ ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් වෙත පිවිසීමට හෝ සමමුහුර්ත කිරීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේ දී සැලකිලිමත් වන්න -- විශ්වාසයකින් තොරව සමාජ ජාලවල ඔබගේ සහ ඔබගේ යහළුවන් අතර සන්නිවේදන කියවීමට මෙමගින් යෙදුමට අවසර දෙයි. සටහන: සියලු සමාජ ජාලවල මෙම අවසරය බල නොකරයි."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ඔබගේ සමාජ ප්රවාහය වෙත ලිවීම"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් පෙන්වීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේදී සැලකිලිමත් වන්න -- යහළුවෙක්ගෙන් පැමිණෙන ලෙස පණිවිඩ නිපදවීමට මෙමඟින් යෙදුමට අවසර දෙන්න. සටහන : සියලු සමාජ ජාල සඳහා මෙම අවසරය බල නොදෙයි."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"දින දර්ශනයේ සිදුවීම් සහ රහසිගත තොරතුරු කියවීම"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ඔබගේ ටැබ්ලටය තුල ගබඩා කර ඇති මිතුරන්ගේ සහ එක්ව ක්රියාකරන්නන්ගේ ද ඇතුළුව සියලුම දින දර්ශන සිද්ධි කියවීමට යෙදුමට අවසර දෙන්න. මෙය රහස්යභාවය හෝ සංවේදීතාවය නොසලකා ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ඔබගේ රූපවාහිනියේ ගබඩා කර ඇති මිතුරන්ගේ සහ එකට වැඩ කරන්නන්ගේ සියළුම දින දර්ශනය සිදුවීම් කියවීමට යෙදුම ඉඩ දෙන්න. නොසලකන හෝ රහසිගත සියළුම දින දර්ශන දත්ත බෙදාගැනීමට හෝ සුරැකීමට යෙදුමට මෙයින් අවසර ලැබේ."</string>
@@ -383,7 +369,7 @@
<string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ටැබ්ලටයේ අධෝරක්ත සම්ප්රේෂකය භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"යෙදුමට රූපවාහිනියේ අධෝරක්ත සම්ප්රේෂකය භාවිතා කිරීමට අවසර දෙයි."</string>
<string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"දුරකථනයේ අධෝරක්ත සම්ප්රේෂකය භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
- <string name="permlab_setWallpaper" msgid="6627192333373465143">"බිතුපත සැකසීම"</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"වෝල්පේපරය සැකසීම"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"පද්ධති බිතුපත සැකසීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"ඔබගේ බිතුපතේ ප්රමාණය සැකසීම"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"පද්ධති බිතුපතේ ප්රමාණ ඉඟි සකස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුම සමඟ පුද්ගල යෙදුම සමමුහුර්ත කිරීම සක්රිය කිරීමට භාවිත කල හැක."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"සමමුහුර්ත කිරීමේ සංඛ්යාන කියවීම"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"සමමුහුර්ත කිරීමේ සිදුවීම් ඉතිහාසය සහ කෙතරම් දත්ත සමමුහුර්ත වී ඇතිදැයි ඇතුලත් ගිණුම සඳහා සමමුහුර්ත කිරීමේ සංඛ්යාන කියවීමට යෙදුමට අවසර දෙන්න."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"ඔබ විසින් ශබ්දකෝෂයට ඇතුළත්කොට ඇති කොන්දේසි කියවීම"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"පරිශීලක ශබ්ද කෝෂයේ පරිශීලකයන් විසින් ගබඩා කර තිබිය හැකි වචන, නම්, වාක්යංශ කියවීමට යෙදුමට අවසර දෙන්න."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"පරිශීලකයින් අර්ථ දැක්වූ ශබ්ද කෝෂයට වචන එකතු කිරීම"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"පරිශීලක ශබ්දකෝෂය තුළට අලුත් වචන ලිවීමට යෙදුමට ඉඩ දෙන්න."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"ඔබගේ USB ආචයනය හි අන්තර්ගතය කියවන්න"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ඔබගේ SD කාඩ් පතෙහි අන්තර්ගතය කියවන්න"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"යෙදුමට ඔබගේ USB ආචයනය අන්තර්ගතය කියවීමට අවසර දෙන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 124bef9..4305487 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,32 +226,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"prístup k polohe tohto zariadenia"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vaše sociálne informácie"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Priamy prístup k informáciám o vašich kontaktoch a sociálnych prepojeniach."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"prístup ku kalendáru"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"posielanie a zobrazovanie správ SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Úložisko"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"prístup k fotkám, médiám a súborom na zariadení"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Používateľský slovník"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čítanie a zadávanie slov v používateľskom slovníku."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Záložky a história"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Priamy prístup k záložkám a histórii prehliadača."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofón"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"zaznamenávanie zvuku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotenie a zaznamenávanie videí"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefón"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonovanie a správa hovorov"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"prístup k informáciám o vašich životných funkciách a fyzickej aktivite"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"prístup k údajom senzorov o životných funkciách"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načítať obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Môžete preskúmať obsah okna, s ktorým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnúť funkciu Preskúmanie dotykom"</string>
@@ -335,16 +329,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje aplikácii upravovať denník hovorov vo vašom tablete vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Umožňuje aplikácii upravovať denník hovorov vo vašom televízore vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje aplikácii upravovať denník hovorov vo vašom telefóne vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"čítať vlastnú kartu kontaktu"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Umožňuje aplikácii čítať informácie v osobnom profile uložené v zariadení, ako je vaše meno a kontaktné informácie. Znamená to, že vás ostatné aplikácie môžu identifikovať a odoslať informácie o vašom profile iným aplikáciám."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"upraviť vlastnú kartu kontaktu"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje aplikácii zmeniť alebo pridať do osobného profilu informácie uložené vo vašom zariadení, ako je vaše meno a kontaktné informácie. Znamená to, že vás aplikácia môže identifikovať a odoslať informácie o vašom profile ostatným aplikáciám."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"telesné senzory (napr. snímače tepu)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Umožňuje aplikácii získať prístup k údajom senzorov monitorujúcich vašu fyzickú kondíciu (napríklad pulz)."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čítať váš sociálny stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje aplikácii pristupovať k sociálnym aktualizáciám od vás a vašich priateľov a synchronizovať ich. Pri zdieľaní informácií dávajte pozor – toto povolenie umožňuje aplikácii čítať komunikáciu medzi vami a vašimi priateľmi v sociálnych sieťach, a to bez ohľadu na jej dôvernosť. Poznámka: Toto povolenie nie je možné vynucovať v prípade všetkých sociálnych sietí."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"písať do vášho sociálneho streamu"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Umožňuje aplikácii zobraziť sociálne aktualizácie od vašich priateľov. Pri zdieľaní informácií dávajte pozor – toto povolenie umožňuje aplikácii vytvárať správy, ktoré zdanlivo pochádzajú od vašich priateľov. Poznámka: Toto povolenie nie je možné vynucovať v prípade všetkých sociálnych sietí."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"čítať udalosti v kalendári a dôverné informácie"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Umožňuje aplikácii čítať všetky udalosti kalendára uložené v tablete vrátane udalostí priateľov alebo spolupracovníkov. Aplikácii to umožní zdieľať alebo ukladať údaje kalendára bez ohľadu na dôvernosť či citlivosť týchto údajov."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Umožňuje aplikácii čítať všetky udalosti kalendára uložené vo vašom televízore vrátane tých, ktoré zadali vaši priatelia alebo spolupracovníci. Toto povolenie môže aplikácii povoliť zdieľať alebo ukladať vaše údaje kalendára bez ohľadu na ich dôvernosť či citlivosť."</string>
@@ -457,10 +443,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Umožňuje aplikácii upraviť nastavenia synchronizácie v účte. Pomocou tohto povolenia je možné napríklad povoliť synchronizáciu aplikácie Ľudia s účtom."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"čítať štatistické údaje o synchronizácii"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Umožňuje aplikácii čítať štatistické informácie o synchronizácii v účte vrátane histórie uskutočnených synchronizácií a informácií o množstve synchronizovaných údajov."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"čítať výrazy pridané do slovníka"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Umožňuje aplikácii čítať všetky slová, názvy a frázy, ktoré mohol používateľ uložiť do svojho slovníka."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"pridať slová do slovníka definovaného používateľom"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje aplikácii zapisovať nové slová do používateľského slovníka."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"čítať obsah úložiska USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čítať obsah SD karty"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Povoľuje ap. čítať obsah USB."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index efcdee9..3b355d7 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"dostop do lokacije te naprave"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Podatki v družabnih omrežjih"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Neposreden dostop do podatkov o stikih in družabnih povezav."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Google Koledar"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"pošiljanje in ogled sporočil SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"dostop do fotografij, predstavnosti in datotek v napravi"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Uporabniški slovar"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Branje besed iz uporabniškega slovarja ali pisanje besed vanj."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Zaznamki in zgodovina"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Neposreden dostop do zaznamkov in zgodovine brskalnika."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparat"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiranje in snemanje videoposnetkov"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"opravljanje in upravljanje telefonskih klicev"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Tipala"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"dostop do podatkov o vaših vitalnih znakih in fizični dejavnosti"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tipala telesnih funkcij"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"dostop do podatkov tipala o vaših vitalnih znakih"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pridobiti vsebino okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preverjanje vsebine okna, ki ga uporabljate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklopiti raziskovanje z dotikom"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Aplikaciji dovoli spreminjanje dnevnika klicev v tabličnem računalniku, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Aplikaciji dovoljuje spreminjanje dnevnika klicev v televizorju, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Aplikaciji dovoli spreminjanje dnevnika klicev v telefonu, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"branje vaše osebne vizitke"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Aplikaciji omogoča branje osebnih podatkov v profilu, ki so shranjeni v napravi, na primer ime in podatki za stik. To pomeni, da vas lahko aplikacija prepozna in vaše podatke v profilu pošlje drugim."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"spreminj. vaše osebne vizitke"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Aplikaciji omogoča spreminjanje ali dodajanje osebnih podatkov v profilu, ki so shranjeni v napravi, na primer ime in podatki za stik. To pomeni, da vas lahko aplikacija prepozna in vaše podatke v profilu pošlje drugim."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"tipala telesnih funkcij (npr. merilniki srčnega utripa)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Aplikaciji omogoča dostop do podatkov tipal, ki nadzirajo vaše fizično stanje, med drugim vaš srčni utrip."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"branje vašega družabnega toka"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Aplikaciji omogoča dostop do vaših objav in objav vaših prijateljev v družabnih omrežjih ter njihovo sinhronizacijo. Previdno pri objavljanju informacij – aplikacija lahko s tem bere komunikacijo med vami in prijatelji v družabnih omrežjih, ne glede na zasebnost. Opomba: Tega dovoljenja ni mogoče uveljaviti v vseh družabnih omrežjih."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pisanje v vaš družabni tok"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Aplikaciji omogoča prikaz objav vaših prijateljev v družabnih omrežjih. Previdno pri objavljanju informacij – aplikacija lahko s tem ustvari sporočila, za katera je videti, da jih pošiljajo prijatelji. Opomba: Tega dovoljenja ni mogoče uveljaviti v vseh družabnih omrežjih."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"branje dogodkov v koledarju in zaupnih podatkov"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Aplikaciji omogoča branje vseh dogodkov v koledarju, ki so shranjeni v tabličnem računalniku, vključno z dogodki prijateljev in sodelavcev. S tem lahko aplikacija objavi ali shrani podatke v koledarju, ne glede na njihovo zaupnost ali občutljivost."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Aplikaciji dovoljuje branje vseh dogodkov v koledarju, ki so shranjeni v televizorju, vključno z dogodki prijateljev in sodelavcev. S tem lahko aplikacija deli z drugimi ali shrani podatke v koledarju, ne glede na njihovo zaupnost ali občutljivost."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Aplikaciji omogoča spreminjanje nastavitev sinhronizacije za račun. S tem se lahko na primer omogoči sinhronizacijo aplikacije Ljudje z računom."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"branje statističnih podatkov sinhronizacije"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Aplikaciji omogoča branje statističnih podatkov o sinhronizaciji za račun, vključno z zgodovino dogodkov sinhronizacije in količino sinhroniziranih podatkov."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"branje izrazov, ki ste jih dodali v slovar"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Aplikaciji omogoča, da prebere vse besede, imena in besedne zveze, ki jih je uporabnik morda shranil v uporabniški slovar."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"dodajanje besed v uporabniški slovar"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Aplikaciji omogoča pisanje nove besede v uporabniški slovar."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"branje vsebine pomnilnika USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"branje vsebine kartice SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Aplikaciji omogoča branje vsebine shrambe USB."</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 26dee97..2053443 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"qasu te vendndodhja e kësaj pajisjeje"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informacionet e tua sociale"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Qasje e drejtpërdrejtë në informacionin e kontakteve të tua dhe lidhjeve sociale."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasu te kalendari yt"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"dërgo dhe shiko mesazhet SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Hapësira e ruajtjes"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"qasu te fotografitë, media dhe skedarët në pajisje"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Fjalori i përdoruesit"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Të lexojë ose të shkruajë fjalë në fjalorin e përdoruesit."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Faqeshënuesit dhe historiku"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Qasje të drejtpërdrejtë në faqet e ruajtura si dhe historinë e shfletuesit."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"regjistro audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"bëj fotografi dhe regjistro video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoni"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"kryej dhe menaxho telefonata"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorët"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"qasu tek informacionet për shenjat jetësore dhe aktivitetin tënd fizik"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensorët e trupit"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"qasu tek të dhënat e sensorëve rreth shenjave të tua jetësore"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Nxjerrë përmbajtjen e dritares"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekton përmbajtjen e dritares me të cilën po ndërvepron."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizojë funksionin \"Eksploro me prekje\""</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lejon aplikacionin të modifikojë ditarin e telefonatave të tabletit tënd, përfshirë të dhëna rreth telefonatave hyrëse dhe dalëse. Aplikacione keqdashëse mund ta përdorin këtë leje për të fshirë ose modifikuar ditarin tënd të telefonatave."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Lejon aplikacionin të modifikojë ditarin e telefonatave të televizorit tënd, përfshirë të dhëna rreth telefonatave hyrëse dhe dalëse. Aplikacione keqdashëse mund ta përdorin këtë leje për të fshirë ose modifikuar ditarin tënd të telefonatave."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lejon aplikacionin të modifikojë ditarin e telefonatave të telefonit tënd, përfshirë të dhënat rreth telefonatave hyrëse dhe dalëse. Aplikacionet keqdashëse mund ta përdorin këtë për të fshirë ose modifikuar ditarin tënd të telefonatave."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"lexo kartën tënde të kontakteve"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Lejon aplikacionin të lexojë informacionin personal të profilit të ruajtur në pajisjen tënde, siç është emri yt dhe informacioni i kontaktit. Kjo do të thotë se aplikacioni mund të të identifikojë dhe t\'u dërgojë të tjerëve informacionin e profilit tënd."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"modifiko kartën tënde të kontaktit"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lejon aplikacionin të ndryshojë ose shtojë informacionin personal të profilit të ruajtur në pajisjen tënde, siç është emri yt dhe informacioni i kontaktit. Kjo do të thotë se aplikacioni mund të të identifikojë dhe t\'u dërgojë të tjerëve informacionin e profilit tënd."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"ndjesorët e trupit (si monitorimet e rrahjeve të zemrës)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Lejon aplikacionin të ketë qasje në të dhënat nga ndjesorë që monitorojnë gjendjen tënde fizike, siç janë rrahjet e zemrës."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lexo transmetimin tënd social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lejon aplikacionin të ketë qasje dhe të sinkronizojë përditësime shoqërore nga ty dhe miqtë e tu. Ki kujdes kur ndan informacione - kjo e lejon aplikacionin të lexojë komunikime mes teje dhe miqve të tu në rrjetet sociale, pavarësisht privatësisë. Shënim. Kjo leje nuk mund të zbatohet në të gjitha rrjetet sociale."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"shkruaj në transmetimin tënd social"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Lejon aplikacionin të shfaqë përditësime shoqërore nga miqtë. Ki kujdes kur ndan informacione - kjo e lejon aplikacionin të prodhojë mesazhe që mund të duken se vijnë nga një mik. Shënim. Kjo leje mund të mos zbatohet në të gjithë rrjetet sociale."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"lexo ngjarjet kalendarike si dhe informacionin e privatësisë së tyre"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Lejon aplikacionin të lexojë të gjitha ngjarjet kalendarike të ruajtura në tabletin tënd, përfshirë ato të miqve ose kolegëve. Kjo mund ta lejojë aplikacionin të ndajë ose ruajë të dhënat e tua të kalendarit, pavarësisht privatësisë ose ndjeshmërisë së tyre."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Lejon aplikacionin të lexojë të gjitha ngjarjet kalendarike të ruajtura në televizorin tënd, përfshi ato të miqve apo kolegëve të tu. Kjo mund ta lejojë aplikacionin të ndajë ose ruajë të dhënat kalendarike, pavarësisht privatësisë ose ndjeshmërisë së tyre."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Lejon një aplikacion të modifikojë cilësimet e sinkronizimit për një llogari. Për shembull, kjo mund të përdoret për të mundësuar sinkronizimin e aplikacionit \"Kontaktet\" me një llogari."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"lexo statistikat e sinkronizimit"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Lejon një aplikacion të lexojë statistikat e sinkronizimit për një llogari, përfshirë historikun e ngjarjeve të sinkronizimit dhe se sa të dhëna janë sinkronizuar."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lexo termat që ke shtuar në fjalor"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Lejon aplikacionin të lexojë të gjitha fjalët, emrat dhe frazat që përdoruesi mund të ketë ruajtur në fjalorin e përdoruesit."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"shto fjalë në fjalorin e përcaktuar nga përdoruesi"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Lejon aplikacionin të shkruajë fjalë të reja në fjalorin e përdoruesit."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lexo përmbajtjet e USB-së"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lexo përmbajtjet e kartës tënde SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Lejon aplikacionin të lexojë përmbajtjet e USB-së tënde."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e2209e6..ea1a22d 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,32 +225,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"приступ локацији овог уређаја"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Информације са друштвених мрежа"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Директан приступ информацијама о контактима и друштвеним везама."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступ календару"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"слање и преглед SMS порука"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Складиште"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"приступ сликама, медијима и датотекама на уређају"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Кориснички речник"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Читање или писање речи у корисничком речнику."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Обележивачи и историја"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Директан приступ обележивачима и историји прегледача."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимање аудио снимака"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"снимање слика и видео снимака"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"упућивање телефонских позива и управљање њима"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"приступ информацијама о виталним функцијама и физичким активностима"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"приступ подацима сензора о виталним функцијама"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преузима садржај прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Укључивање Истраживања додиром"</string>
@@ -334,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дозвољава апликацији да мења евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Дозвољава апликацији да мења евиденцију позива на ТВ-у, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дозвољава апликацији да мења евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"читање ваше контакт картице"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Дозвољава апликацији да чита личне информације о профилу ускладиштене на уређају, као што су име и контакт информације. То значи да апликација може да вас идентификује и шаље другима информације о профилу."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"измена ваше контакт картице"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Дозвољава апликацији да мења или додаје нове личне информације о профилу ускладиштене на уређају, као што су име и контакт информације. То значи да апликација може да вас идентификује и шаље другима информације о профилу."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (нпр. срчани монитор)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Дозвољава апликацији да приступа подацима са сензора који надгледају физичку кондицију, као што је број откуцаја срца."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читање друштвеног стрима"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Дозвољава апликацији да приступа вашим друштвеним ажурирањима и друштвеним ажурирањима пријатеља и да их синхронизује. Будите опрезни када делите информације – ово омогућава апликацији да чита преписке између вас и пријатеља на друштвеним мрежама, без обзира на поверљивост. Напомена: Ова дозвола се можда не примењује на све друштвене мреже."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писање у друштвени стрим"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Дозвољава апликацији да приказује друштвена ажурирања пријатеља. Будите опрезни када делите информације – ово омогућава апликацији да прави поруке које изгледају као да их шаљу пријатељи. Напомена: Ова дозвола се можда не примењује на свим друштвеним мрежама."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"читање календарских догађаја и поверљивих информација"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Дозвољава апликацији да чита све догађаје календара ускладиштене на таблету, укључујући догађаје пријатеља или колега. Ово може да омогући апликацији да дели или чува податке календара, без обзира на поверљивост или осетљивост."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Дозвољава апликацији да чита све догађаје из календара које чувате на ТВ-у, укључујући и оне који припадају пријатељима или колегама. То може да дозволи апликацији да дели или чува податке из календара, независно од поверљивости или осетљивости."</string>
@@ -456,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Дозвољава апликацији да мења подешавања синхронизације за налог. На пример, овако може да се омогући синхронизација апликације Људи са налогом."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"читање статистике о синхронизацији"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Дозвољава апликацији да чита статистику синхронизације за налог, укључујући историју синхронизованих догађаја и количину података који се синхронизују."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"читање термина које сте додали у речник"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Дозвољава апликацији да чита све речи, називе и фразе које је корисник можда сачувао у корисничком речнику."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"додавање речи у речник корисника"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дозвољава апликацији да уписује нове речи у кориснички речник."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"читање садржаја USB меморије"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"читање садржаја SD картице"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Омогућава апликацији да чита садржај USB меморије."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3f7de17..22584f6 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Plats"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"komma åt enhetens platsuppgifter"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Dina sociala uppgifter"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direktåtkomst till information om dina kontakter och sociala kontakter."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tillgång till din kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"skicka och visa sms"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"få åtkomst till foton, media och filer på din enhet"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Egen ordlista"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Läsa eller skriva ord i användarordlistan."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bokmärken och historik"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direktåtkomst till bokmärken och webbläsarhistorik."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"spela in ljud"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder och spela in video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Mobil"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ringa och hantera telefonsamtal"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"få åtkomst till information om dina vitalparametrar och din fysiska aktivitet"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Kroppssensorer"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"få åtkomst till sensordata om dina vitalparametrar"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hämta fönsterinnehåll"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Granska innehållet i ett fönster som du interagerar med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by Touch"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tillåter att appen gör ändringar i pekdatorns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Tillåter att appen gör ändringar i tv:ns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga appar kan använda detta för att rensa eller ändra din samtalslista."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tillåter att appen gör ändringar i mobilens samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"läsa ditt eget kontaktkort"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Tillåter att appen läser personliga profiluppgifter som sparats på din enhet, t.ex. ditt namn och kontaktuppgifter. Det innebär att appen kan identifiera dig och skicka profiluppgifter till andra."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"ändra ditt eget kontaktkort"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tillåter att appen ändrar eller lägger till personliga profiluppgifter som sparats på din enhet, till exempel ditt namn och dina kontaktuppgifter. Det innebär att appen kan identifiera dig och skicka profiluppgifter till andra."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kroppssens. (för hjärtat m.m.)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ger appen åtkomst till information från sensorer om ditt fysiska tillstånd, till exempel din puls."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"läs mitt sociala flöde"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tillåter att appen kommer åt och synkroniserar sociala uppdateringar från dig och dina vänner. Var försiktig när du delar information – med den här behörigheten tillåts appen att läsa kommunikation mellan dig och dina vänner på sociala nätverk oavsett sekretessnivå. Observera att den här behörigheten kanske inte är tillämplig på alla sociala nätverk."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skriv till mitt sociala flöde"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tillåter att appen visar sociala uppdateringar från dina vänner. Var försiktig när du delar information – med den här behörigheten tillåts appen att generera meddelanden som kan se ut att komma från en vän. Observera att den här behörigheten kanske inte är tillämplig på alla sociala nätverk."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"läsa kalenderuppgifter plus konfidentiell information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tillåter att appen läser alla kalenderuppgifter som sparats på surfplattan, inklusive dina vänners eller kollegors uppgifter. Med den här behörigheten kan appen tillåtas att dela eller spara kalenderuppgifter även om de är sekretessbelagda eller känsliga."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Tillåter att appen läser alla kalenderhändelser som sparats på tv:n, bland annat de som tillhör vänner eller kollegor. På så sätt kan appen dela eller spara dina kalenderhändelser oavsett sekretess eller känslighet."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Tillåter att appen ändrar synkroniseringsinställningarna för ett konto. Detta kan användas till exempel för att synkronisera appen Personer med ett konto."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"läsa synkroniseringsstatistik"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Tillåter att appen läser synkroniseringsstatistik för ett konto, inklusive historiken för synkroniseringshändelser och mängden data som synkroniseras."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"läsa termer som du har lagt till i ordlistan"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Tillåter att appen läser alla ord, namn och fraser som användaren har sparat i ordlistan."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"lägga till ord i den användardefinierade ordlistan"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tillåter att appen anger nya ord i användarordlistan."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"läsa innehåll på USB-enheten"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"läsa innehållet på SD-kortet"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Låter appen läsa USB-innehåll."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1dd01bc1..818ee1d 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Mahali"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"fikia mahali kilipo kifaa hiki"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Taarifa yako ya kijamii"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kufikia moja kwa moja taarifa kuhusu anwani zako na miunganisho ya kijamii."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"fikia kalenda yako"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"tuma na uangalie ujumbe wa SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Hifadhi"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"fikia picha, maudhui na faili kwenye kifaa chako"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamusi ya Mtumiaji"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kusoma au kuandika maneno katika kamusi ya mtumiaji."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Alamisho na Historia"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Kufikia, moja kwa moja, alamisho na historia ya kivinjari."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Kipokea sauti"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekodi sauti"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"piga picha na urekodi video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Vihisi"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"fikia maelezo kuhusu alama zako muhimu na shughuli ya kimwili"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Vihisi vya Mwili"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kihisi kuhusu alama zako muhimu"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Rejesha maudhui ya dirisha"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Chunguza maudhui ya dirisha unaloingiliana nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Washa Chunguza kwa Mguso"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Huruhusu programu kurekebisha rajisi ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Huruhusu programu kurekebisha rajisi ya runinga yako, ikiwa ni pamoja na data ya simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Huruhusu programu kurekebisha rajisi ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"kusoma kadi yako ya mawasiliano"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Inaruhusu programu kusoma taarifa ya kibinafsi ya maelezo mafupi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kuwatumia wengine taarifa yako ya maelezo mafupi."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"vipima hali ya mwili (kama mpigo wa moyo)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Huruhusu programu kufikia data kutoka vihisi vinavyofuatilia hali yako ya kimwili, kama vile mapigo ya moyo."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Huruhusu programu kufikia na kupatanisha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii huruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"kuandikia mipasho yako wa kijamii"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Huruhusu programu kuonyesha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yote ya jamii."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Inaruhusu programu kusoma matukio yote ya kalenda yaliohifadhiwa kwenye kompyuta kibao yako, yakijumuisha yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kaelnda, bila kujali usiri au unyeti."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Huruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye runinga yako, ikiwa ni pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kelenda, licha ya usiri au unyeti."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Inaruhusu programu kurekebisha mipangalio ya upatanishi wa akaunti. Kwa mfano, hii inaweza kuwezesha programu ya upatanishi wa Watu na akaunti."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"kusoma takwimu za usawazishaji"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Inaruhusu programu kusoma takwimu za upatanishi za akaunti, ikiwa ni pamoja na historia ya matukio ya upatanishi na kiasi cha data kimepatanishwa."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"soma maneno uliyoongeza kwenye kamusi"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Inaruhusu programu kusoma maneno, majina na misemo yote ambayo mtumiaji alihifadhi katika kamusi ya mtumiaji."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"ongeza maneno katika kamusi ya mtumiaji iliyofafanuliwa"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Inaruhusu programu kuandika maneno mapya katika kamusi ya mtumiaji."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"kusoma maudhui yaliyo kwenye hifadhi yako ya USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"soma maudhui ya kadi yako ya SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Huruhusu programu kusoma maudhui ya hifadhi ya USB."</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 1140cc1..cc9f34b 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"இருப்பிடம்"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"சாதனத்தின் இருப்பிடத்தை அணுகும்"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"உங்கள் சமூகத் தகவல்"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"உங்கள் தொடர்புகள் மற்றும் சமூக இணைப்புகள் குறித்த தகவலுக்கான நேரடி அணுகல்."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"கேலெண்டர்"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"கேலெண்டரை அணுகும்"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS செய்திகளை அனுப்பும் மற்றும் பார்க்கும்"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"சேமிப்பிடம்"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"உங்கள் சாதனத்தில் உள்ள படங்கள், மீடியா மற்றும் கோப்புகளை அணுகும்"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"பயனர் அகராதி"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"பயனர் அகராதியில் சொற்களைப் படிக்கும் அல்லது எழுதும்."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"புத்தகக்குறிகள் மற்றும் வரலாறு"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"புத்தகக்குறிகள் மற்றும் உலாவியின் வரலாற்றுக்கான நேரடி அணுகல்."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"மைக்ரோஃபோன்"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ஆடியோவைப் பதிவுசெய்யும்"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"கேமரா"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"படங்களை எடுக்கும், வீடியோவைப் பதிவுசெய்யும்"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ஃபோன்"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"மொபைல் அழைப்புகளைச் செய்யும், பெறும்"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"உணர்விகள்"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"உங்கள் உடலியக்க குறிகள் மற்றும் உடல் சார்ந்த செயல்பாடு பற்றிய தகவலை அணுகும்"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"உடல் உணர்விகள்"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"உங்கள் உடலியக்கக் குறிகள் பற்றிய உணர்வித் தரவை அணுகும்"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"சாளர உள்ளடக்கத்தைப் பெறுதல்"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"நீங்கள் ஊடாடிக்கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"தொடுவதன் மூலம் அறிவதை இயக்கவும்"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் பயன்பாட்டை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்ளிட்ட உங்கள் டிவியின் அழைப்பு பதிவைத் திருத்த, பயன்பாட்டை அனுமதிக்கிறது. உங்கள் அழைப்பு பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் பயன்பாட்டை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"உங்கள் சொந்த தொடர்பு அட்டையைப் படித்தல்"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"உங்கள் பெயர் மற்றும் தொடர்பு தகவல் போன்ற, உங்கள் சாதனத்தில் சேமிக்கப்பட்ட தனிப்பட்ட சுயவிவரத் தகலைப் படிக்கப் பயன்பாட்டை அனுமதிக்கிறது, இதற்கு அர்த்தம், பயன்பாடு உங்களைக் அடையாளங்காணலாம் மற்றும் உங்கள் சுயவிவரத் தகவலைப் பிறருக்கு அனுப்பலாம் என்பதாகும்."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"உங்கள் சொந்த தொடர்பு அட்டையை மாற்றுதல்"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"உங்கள் சாதனத்தில் சேமிக்கப்பட்ட உங்கள் பெயர் மற்றும் தொடர்பு தகவல் போன்ற தனிப்பட்ட சுயவிவரத் தகவலை மாற்ற அல்லது சேர்க்க பயன்பாட்டை அனுமதிக்கிறது. அதாவது பயன்பாடு உங்களை அடையாளப்படுத்தலாம், உங்கள் சுயவிவரத் தகவலை மற்றவர்களுக்கு அனுப்பலாம்."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"உடல் உணர்விகள் (இதயத்துடிப்பு கண்காணித்தல் போன்றவை)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக பயன்பாடுகளை அனுமதிக்கும்."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"எனது சமூக ஸ்ட்ரீமைப் படித்தல்"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"உங்களிடமிருந்தும், உங்கள் நண்பர்களிடமிருந்தும் வரும் சமூகப் புதுப்பிப்புகளை அணுகி ஒத்திசைக்கப் பயன்பாட்டை அனுமதிக்கிறது. தகவலைப் பகிரும்போது எச்சரிக்கையாக இருக்கவும் -- ரகசியத்தன்மையைப் பொருட்படுத்தாமல், சமூக நெட்வொர்க்குகளில் உங்களுக்கும், உங்கள் நண்பர்களுக்கிடையேயும் உள்ள தொடர்புகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது. குறிப்பு: இந்த அனுமதி எல்லா சமூக நெட்வொர்க்குகளிலும் செயல்படுத்தப்படாமல் இருக்கலாம்."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"உங்கள் சமூக ஸ்ட்ரீமில் எழுதுக"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"உங்கள் நண்பர்களிடமிருந்து வரும் சமூக அறிவிப்புகளைக் காண்பிக்க பயன்பாட்டை அனுமதிக்கிறது. தகவலைப் பகிர்வதில் கவனமாக இருங்கள் -- நண்பரிடமிருந்து வரும் செய்திகளை உருவாக்க பயன்பாட்டை அனுமதிக்கிறது. குறிப்பு: இந்த அனுமதி எல்லா சமூக நெட்வொர்க்குகளிலும் செயல்படுத்தப்படாமல் இருக்கலாம்."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"கேலெண்டர் நிகழ்வுகளையும், ரகசிய தகவலையும் படித்தல்"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"நண்பர்கள் அல்லது சகப் பணியாளர்கள் ஆகியோரின் நிகழ்வுகளையும் சேர்த்து, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட எல்லா கேலெண்டர் நிகழ்வுகளையும் படிக்க பயன்பாட்டை அனுமதிக்கிறது. உங்கள் கேலெண்டர் தரவின் ரகசியத்தன்மை அல்லது முக்கியத்துவத்தைப் பொருட்படுத்தாமல் அதனைப் பகிர அல்லது சேமிக்க பயன்பாட்டை இது அனுமதிக்கிறது."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"நண்பர்கள் அல்லது சகப் பணியாளர்களின் நிகழ்வுகள் உள்ளிட்ட உங்கள் டிவியில் சேமிக்கப்பட்ட எல்லா கேலெண்டர் நிகழ்வுகளையும் படிக்க, பயன்பாட்டை அனுமதிக்கிறது. தரவின் ரகசியத்தன்மை அல்லது அதன் முக்கியத்துவத்தைப் பொருட்படுத்தாமல், உங்கள் கேலெண்டர் தரவைப் பகிர அல்லது சேமிக்க, இது பயன்பாட்டை அனுமதிக்கலாம்."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"கணக்கிற்கான ஒத்திசைவு அமைப்புகளைத் திருத்த பயன்பாட்டை அனுமதிக்கிறது. எடுத்துக்காட்டாக, பீப்பிள் பயன்பாட்டைக் கணக்குடன் ஒத்திசைவை இயக்குவதற்கு இது பயன்படுத்தப்படலாம்."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"ஒத்திசைவு புள்ளிவிவரங்களைப் படித்தல்"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"நிகழ்வுகள் ஒத்திசைவின் வரலாறு மற்றும் ஒத்திசைக்கப்பட்ட தரவு எவ்வளவு ஆகியன உட்பட, கணக்கிற்கான ஒத்திசைவு புள்ளிவிவரங்களைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"அகராதியில் நீங்கள் சேர்த்த சொற்களைப் படித்தல்"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"பயனர் அகராதியில் பயனர் சேமித்திருக்கக்கூடிய எல்லா வார்த்தைகள், பெயர்கள் மற்றும் சொற்றொடர்களைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"பயனர் வரையறுத்த அகராதியில் வார்த்தைகளைச் சேர்த்தல்"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"பயனர் அகராதியில் புதிய சொற்களை எழுத, பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"உங்கள் USB சேமிப்பிடத்தின் உள்ளடக்கங்களைப் படித்தல்"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"உங்கள் SD கார்டின் உள்ளடக்கங்களைப் படித்தல்"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"உங்கள் USB சேமிப்பிடத்தின் உள்ளடக்கங்களைப் படிக்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
@@ -645,7 +626,7 @@
<string name="relationTypeDomesticPartner" msgid="6904807112121122133">"வாழ்வுத் துணை"</string>
<string name="relationTypeFather" msgid="5228034687082050725">"தந்தை"</string>
<string name="relationTypeFriend" msgid="7313106762483391262">"நண்பர்"</string>
- <string name="relationTypeManager" msgid="6365677861610137895">"நிர்வாகி"</string>
+ <string name="relationTypeManager" msgid="6365677861610137895">"மேலாளர்"</string>
<string name="relationTypeMother" msgid="4578571352962758304">"தாய்"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"பெற்றோர்"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"கூட்டாளர்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 115c1cc..e96403a 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"ఈ పరికర స్థానాన్ని ప్రాప్యత చేయడానికి అనుమతి"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"మీ సామాజిక సమాచారం"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"మీ పరిచయాలు మరియు సామాజిక బాంధవ్యాలకు సంబంధించిన సమాచారానికి ప్రత్యక్ష ప్రాప్యత."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"క్యాలెండర్"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్ను ప్రాప్యత చేస్తుంది"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS సందేశాలను పంపుతుంది మరియు వీక్షిస్తుంది"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"నిల్వ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్లను ప్రాప్యత చేస్తుంది"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"వినియోగదారు నిఘంటువు"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"వినియోగదారు నిఘంటువులో పదాలు చదువుతుంది లేదా వ్రాస్తుంది."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"బుక్మార్క్లు మరియు చరిత్ర"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"బుక్మార్క్లు మరియు బ్రౌజర్ చరిత్రకు ప్రత్యక్ష ప్రాప్యత."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"మైక్రోఫోన్"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ఆడియోను రికార్డ్ చేస్తుంది"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"కెమెరా"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"చిత్రాలను తీస్తుంది మరియు వీడియోను రికార్డ్ చేస్తుంది"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ఫోన్"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ఫోన్ కాల్లను చేస్తుంది మరియు నిర్వహిస్తుంది"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"సెన్సార్లు"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"మీ అత్యంత కీలకమైన గుర్తులు మరియు భౌతిక కార్యాచరణ గురించి సమాచారాన్ని ప్రాప్యత చేస్తుంది"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"శరీర సెన్సార్లు"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"మీ అత్యంత కీలకమైన గుర్తుల గురించి సెన్సార్ డేటాని ప్రాప్యత చేస్తుంది"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్ను తిరిగి పొందుతుంది"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్ను పరిశీలించండి."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభిస్తుంది"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్ల గురించిన డేటాతో సహా మీ టాబ్లెట్ యొక్క కాల్ లాగ్ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్లకు సంబంధించిన డేటాతో సహా మీ టీవీ కాల్ లాగ్ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్ను తీసివేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్ల గురించిన డేటాతో సహా మీ ఫోన్ యొక్క కాల్ లాగ్ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"మీ స్వంత సంప్రదింపు కార్డును చదవడం"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"మీ పరికరంలో నిల్వ చేయబడిన వ్యక్తిగత ప్రొఫైల్ సమాచారాన్ని అనగా మీ పేరు మరియు సంప్రదింపు సమాచారం వంటివి చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మిమ్మల్ని గుర్తించగలదని మరియు మీ ప్రొఫైల్ సమాచారాన్ని ఇతరులకు పంపించగలదని దీని అర్థం."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"మీ స్వంత సంప్రదింపు కార్డును సవరించడం"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"మీ పరికరంలో నిల్వ చేయబడిన వ్యక్తిగత ప్రొఫైల్ సమాచారాన్ని అనగా మీ పేరు మరియు సంప్రదింపు సమాచారం వంటివి మార్చడానికి లేదా జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మిమ్మల్ని గుర్తించగలదని మరియు మీ ప్రొఫైల్ సమాచారాన్ని ఇతరులకు పంపగలదని దీని అర్థం."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"శరీర సెన్సార్లు (హృదయ స్పందన మానిటర్లు వంటివి)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"మీ శారీరక పరిస్థితిని అనగా మీ గుండె స్పందన రేటు వంటి వాటిని పర్యవేక్షించే సెన్సార్ల నుండి డేటాను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"మీ సామాజిక ప్రసారాన్ని చదవడం"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"మీరు మరియు మీ స్నేహితులు సమర్పించిన తాజా సామాజిక విషయాలను ప్రాప్యత చేయడానికి మరియు సమకాలీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సమాచారాన్ని భాగస్వామ్యం చేస్తున్నప్పుడు జాగ్రత్తగా ఉండండి -- ఇది గోప్యతతో సంబంధం లేకుండా, మీ మధ్య మరియు మీ స్నేహితుల మధ్య జరిగిన కమ్యూనికేషన్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. గమనిక: ఈ అనుమతి అన్ని సామాజిక నెట్వర్క్ల్లో అమలు చేయబడకపోవచ్చు."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"మీ సామాజిక ప్రసారానికి వ్రాయడం"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"మీ స్నేహితుల నుండి తాజా సామాజిక విషయాలను ప్రదర్శించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సమాచారాన్ని భాగస్వామ్యం చేసేటప్పుడు జాగ్రత్తగా ఉండండి -- ఇది మీ స్నేహితుల నుండి వచ్చినట్లుగా కనిపించే రీతిలో సందేశాలను రూపొందించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. గమనిక: ఈ అనుమతి అన్ని సామాజిక నెట్వర్క్ల్లో అమలు చేయబడకపోవచ్చు."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"క్యాలెండర్ ఈవెంట్లతో పాటు గోప్యమైన సమాచారాన్ని చదవడం"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"స్నేహితులు లేదా సహోద్యోగులకు సంబంధించిన ఈవెంట్లతో సహా మీ టాబ్లెట్లో నిల్వ చేయబడిన అన్ని క్యాలెండర్ ఈవెంట్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది గోప్యత లేదా తీవ్రతతో సంబంధం లేకుండా మీ క్యాలెండర్ డేటాను భాగస్వామ్యం చేయడానికి లేదా సేవ్ చేయడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"స్నేహితులు లేదా సహోద్యోగులకు సంబంధించిన ఈవెంట్లతో సహా మీ టీవీలో నిల్వ చేసిన అన్ని క్యాలెండర్ ఈవెంట్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది గోప్యత లేదా తీవ్రతతో సంబంధం లేకుండా మీ క్యాలెండర్ డేటాను భాగస్వామ్యం చేయడానికి లేదా సేవ్ చేయడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, ఇది ఒక ఖాతాతో వ్యక్తుల అనువర్తనం యొక్క సమకాలీకరణను ప్రారంభించడానికి ఉపయోగించబడవచ్చు."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"సమకాలీకరణ గణాంకాలను చదవడం"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ఖాతా యొక్క సమకాలీకరణ గణాంకాలను అలాగే సమకాలీకరణ ఈవెంట్ల చరిత్రను మరియు ఎంత డేటా సమకాలీకరించబడింది అనేవాటిని చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"మీరు నిఘంటువుకు జోడించిన పదాలను చదవడం"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"వినియోగదారు నిఘంటువులో వినియోగదారు నిల్వ చేసిన అన్ని పదాలు, పేర్లు మరియు పదబంధాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"వినియోగదారు-నిర్వచిత నిఘంటువుకు పదాలను జోడించడం"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"వినియోగదారు నిఘంటువులోకి కొత్త పదాలను వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"మీ USB నిల్వ యొక్క కంటెంట్లను చదవడం"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"మీ SD కార్డు యొక్క కంటెంట్లను చదవడం"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"మీ USB నిల్వలోని కంటెంట్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0b37f27..813c61f 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"เข้าถึงตำแหน่งของอุปกรณ์นี้"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ข้อมูลทางสังคมของคุณ"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"เข้าถึงข้อมูลเกี่ยวกับผู้ติดต่อและเครือข่ายสังคมของคุณโดยตรง"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ปฏิทิน"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"เข้าถึงปฏิทิน"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"ส่งและดูข้อความ SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"พื้นที่เก็บข้อมูล"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"เข้าถึงรูปภาพ สื่อ และไฟล์บนอุปกรณ์ของคุณ"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"พจนานุกรมผู้ใช้"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"อ่านหรือเขียนคำในพจนานุกรมผู้ใช้"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"บุ๊กมาร์กและประวัติ"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"เข้าถึงบุ๊กมาร์กและประวัติของเบราว์เซอร์โดยตรง"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ไมโครโฟน"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"บันทึกเสียง"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"กล้องถ่ายรูป"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ถ่ายภาพและบันทึกวิดีโอ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"โทรศัพท์"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"โทรและจัดการการโทร"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"เซ็นเซอร์"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"เข้าถึงข้อมูลเกี่ยวกับสัญญาณชีพและกิจกรรมทางกายภาพ"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"เซ็นเซอร์สำหรับร่างกาย"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"เข้าถึงข้อมูลเซ็นเซอร์เกี่ยวกับสัญญาณชีพของคุณ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"เปิด \"แตะเพื่อสำรวจ\""</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"อนุญาตให้แอปแก้ไขประวัติการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"อนุญาตให้แอปแก้ไขประวัติการโทรของทีวี รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและโทรออก แอปที่เป็นอันตรายอาจใช้สิทธิ์นี้เพื่อลบหรือแก้ไขประวัติการโทรได้"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"อนุญาตให้แอปแก้ไขประวัติการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"อ่านบัตรผู้ติดต่อของคุณเอง"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"อนุญาตให้แอปพลิเคชันอ่านข้อมูลส่วนตัวในโปรไฟล์ที่จัดเก็บไว้ในอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลติดต่อของคุณ ซึ่งหมายความว่าแอปพลิเคชันสามารถระบุตัวคุณและอาจส่งข้อมูลโปรไฟล์ของคุณให้ผู้อื่น"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"แก้ไขบัตรผู้ติดต่อของคุณเอง"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงหรือเพิ่มข้อมูลโปรไฟล์ส่วนตัวที่จัดเก็บไว้บนอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลติดต่อ ซึ่งหมายความว่าแอปพลิเคชันจะสามารถระบุตัวตนของคุณและส่งข้อมูลโปรไฟล์ของคุณให้แก่ผู้อื่นได้"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"เซ็นเซอร์ร่างกาย (เช่น วัดอัตราการเต้นของหัวใจ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"อนุญาตให้แอปเข้าถึงข้อมูลจากเซ็นเซอร์ที่ตรวจสอบสภาพทางกายภาพ เช่น อัตราการเต้นของหัวใจ"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"อ่านสตรีมเครือข่ายสังคม"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"อนุญาตให้แอปพลิเคชันเข้าถึงและซิงค์การอัปเดตทางสังคมจากคุณและเพื่อน โปรดแชร์ข้อมูลอย่างระมัดระวังเนื่องจากการอนุญาตนี้ทำให้แอปพลิเคชันสามารถอ่านการติดต่อระหว่างคุณและเพื่อนในเครือข่ายสังคมได้ ไม่ว่าจะมีการรักษาข้อมูลที่เป็นความลับแบบใดก็ตาม หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับทุกเครือข่ายสังคม"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"เขียนในสตรีมเครือข่ายสังคม"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"อนุญาตให้แอปพลิเคชันแสดงการอัปเดตทางสังคมจากเพื่อนของคุณ โปรดแชร์ข้อมูลอย่างระมัดระวังเนื่องจากการอนุญาตนี้ทำให้แอปพลิเคชันสามารถสร้างข้อความที่ดูเหมือนมาจากเพื่อนได้ หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้ได้กับทุกเครือข่ายสังคม"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"อ่านกิจกรรมบนปฏิทินรวมถึงข้อมูลที่เป็นความลับ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"อนุญาตให้แอปพลิเคชันอ่านกิจกรรมในปฏิทินทั้งหมดที่จัดเก็บไว้ในแท็บเล็ตของคุณ ซึ่งรวมถึงกิจกรรมของเพื่อนหรือเพื่อนร่วมงานด้วย ซึ่งอาจทำให้แอปพลิเคชันสามารถแชร์หรือบันทึกข้อมูลในปฏิทินของคุณได้ไม่ว่าจะมีการรักษาข้อมูลที่เป็นความลับหรือหรือข้อมูลที่อ่อนไหวแบบใดก็ตาม"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"อนุญาตให้แอปอ่านกิจกรรมทั้งหมดในปฏิทินที่เก็บไว้ในทีวี รวมถึงกิจกรรมของเพื่อนๆ หรือเพื่อนร่วมงาน โดยอาจอนุญาตให้แอปแชร์หรือบันทึกข้อมูลปฏิทิน แม้ว่าจะเป็นข้อมูลลับหรือข้อมูลละเอียดอ่อน"</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงการตั้งค่าการซิงค์ของบัญชี ตัวอย่างเช่น สามารถใช้การอนุญาตเปิดใช้งานการซิงค์แอปพลิเคชัน People กับบัญชี"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"อ่านสถิติการซิงค์"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"อนุญาตให้แอปพลิเคชันอ่านสถานะการซิงค์ของบัญชี ซึ่งรวมถึงประวัติกิจกรรมการซิงค์และปริมาณข้อมูลที่ซิงค์"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"อ่านคำที่คุณเพิ่มลงในพจนานุกรม"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"อนุญาตให้แอปพลิเคชันอ่านคำ ชื่อ และวลีทั้งหมดที่ผู้ใช้ได้จัดเก็บไว้ในพจนานุกรมผู้ใช้"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"เพิ่มคำลงในพจนานุกรมที่ผู้ใช้กำหนด"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"อนุญาตให้แอปพลิเคชันเขียนคำใหม่ลงในพจนานุกรมผู้ใช้"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"อ่านเนื้อหาในที่จัดเก็บ USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"อ่านเนื้อหาในการ์ด SD ของคุณ"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"อนุญาตให้แอปอ่านเนื้อหาในที่จัดเก็บข้อมูล USB"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6dd35d4..4b0cba6 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasyon"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"i-access ang lokasyon ng device na ito"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ang iyong social na impormasyon"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direktang access sa impormasyon tungkol sa iyong mga contact at social na koneksyon."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendaryo"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ina-access ang iyong kalendaryo"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"magpadala at tumingin ng mga mensaheng SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Imbakan"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"mag-access ng mga larawan, media at file sa iyong device"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diksyunaryo ng User"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Magbasa o magsulat ng mga salita sa diksyunaryo ng user"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Mga Bookmark at Kasaysayan"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direktang access sa mga bookmark at kasaysayan ng browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikropono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"nagre-record ng audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"kumukuha ng mga larawan at nagre-record ng video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"tumatawag sa telepono at namamahala sa mga tawag sa telepono"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Mga Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"i-access ang impormasyon tungkol sa iyong mahahalagang senyales at pisikal na aktibidad"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Mga Sensor ng Katawan"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"i-access ang data ng sensor tungkol sa iyong mahahalagang senyales"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Kunin ang content ng window"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Siyasatin ang nilalaman ng isang window kung saan ka nakikipag-ugnayan."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"I-on ang Explore by Touch"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong tablet, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong TV, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng mga nakakahamak na app upang burahin o baguhin ang iyong log ng tawag."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong telepono, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"basahin sarili mo contact card"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Pinapayagan ang app na basahin ang personal na impormasyon ng profile na naka-imbak sa iyong device, gaya ng iyong pangalan at impormasyon sa pakikipag-ugnay. Nangangahulugan ito na makikilala ka ng app at maaari nitong ipadala ang impormasyon ng iyong profile sa iba."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"baguhin sarili mo contact card"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pinapayagan ang app na baguhin ang o magdagdag sa personal na impormasyon ng profile na naka-imbak sa iyong device, gaya ng iyong pangalan at impormasyon sa pakikipag-ugnay. Nangangahulugan ito na makikilala ka ng app at maaari nitong ipadala ang impormasyon ng iyong profile sa iba."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"mga sensor sa katawan (gaya ng mga heart rate monitor)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Pinapayagan ang app na i-access ang data mula sa mga sensor na sumusubaybay sa iyong pisikal na kundisyon, tulad ng iyong heart rate."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"basahin ang iyong social stream"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Pinapayagan ang app na mag-access at mag-sync ng mga social na update mula sa iyo at sa iyong mga kaibigan. Maging maingat kapag nagbabahagi ng impormasyon -- pinapayagan nito ang app na magbasa ng mga pakikipag-ugnayan sa pagitan mo at ng iyong mga kaibigan sa mga social network, ano pa man ang katayuan sa pagiging kumpedensyal nito. Tandaan: hindi maaaring ipatupad ang pahintulot na ito sa lahat ng social network."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"magsulat sa iyong social stream"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Pinapayagan ang app na magpakita ng mga social na update mula sa iyong mga kaibigan. Maging maingat kapag nagbabahagi ng impormasyon -- pinapayagan nito ang app na bumuo ng mga mensaheng maaaring lumitaw na mula sa isang kaibigan. Tandaan: hindi maaaring ipatupad ang pahintulot na ito sa lahat ng social network."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"magbasa ng mga kaganapan sa kalendaryo kasama ang kumpedensyal na impormasyon"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Pinapayagan ang app na basahin ang lahat ng kaganapan sa kalendaryo na naka-imbak sa iyong tablet, kabilang iyong sa mga kaibigan o katrabaho. Maaari nitong payagan ang app na ibahagi o i-save ang data ng iyong kalendaryo, ano pa man ang katayuan ng pagiging kumpedensyal o sensitibo nito."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Nagbibigay-daan sa app na mabasa ang lahat ng mga kaganapan sa kalendaryo na nakaimbak sa iyong TV, kabilang ang mga kaganapan mula sa iyong mga kaibigan o katrabaho. Maaaring payagan nito ang app na magbahagi o mag-save ng iyong data ng kalendaryo kahit na kumpidensyal o sensitibo ito."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Pinapayagan ang isang app na baguhin ang mga setting ng pag-sync para sa isang account. Halimbawa, magagamit ito upang paganahin ang pag-sync ng app na Mga Tao sa isang account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"basahin ang mga istatistika ng sync"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Pinapayagan ang app na basahin ang mga istatistika ng pag-sync para sa isang account, kabilang ang kasaysayan ng mga kaganapan sa pag-sync at kung ilang data ang naka-sync."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"basahin ang mga terminong idinagdag mo sa diksyunaryo"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Pinapayagan ang app na basahin ang lahat ng salita, pangalan at parirala na maaaring inimbak ng user sa diksyunaryo ng user."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"magdagdag ng mga salita sa diksyunaryong tinukoy ng user"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Pinapayagan ang app na magsulat ng mga bagong salita sa diksyunaryo ng user."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"basa nilalaman USB storage mo"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"basahin ang mga nilalaman ng iyong SD card"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Pinapayagan ang app na basahin ang mga nilalaman ng iyong USB storage."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7fd1fc2..f6144c2 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Konum"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"bu cihazın konumuna erişme"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosyal bilgileriniz"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kişileriniz ve sosyal bağlantılarınızla ilgili bilgilere doğrudan erişim."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Takvim"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"takviminize erişme"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS iletileri gönderme ve görüntüleme"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Depolama"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"cihazınızdaki fotoğraflara, medyaya ve dosyalara erişme"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kullanıcı Sözlüğü"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kullanıcı sözlüğündeki kelimeleri okuma veya yazma"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Yer İşaretleri ve Geçmiş"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Yer işaretlerine ve tarayıcı geçmişine doğrudan erişim."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ses kaydetme"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"fotoğraf çekme ve video kaydetme"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon aramaları yapma ve çağrıları yönetme"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensörler"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"hayati belirtileriniz ve fiziksel aktivitenizle ilgili bilgilere erişme"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"hayati belirtilerinizle ilgili sensör verilerine erişme"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pencere içeriğini alma"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Etkileşim kurduğunuz pencerenin içeriğini inceler."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Dokunarak Keşfet\'i açma"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Uygulamaya tabletinizin çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Uygulamaya, tabletinizin çağrı kaydında (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı kaydınızı silebilir veya değiştirebilir."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Uygulamaya telefonunuzun çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"kendi kişi kartımı oku"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Uygulamaya adınız ve iletişim bilgileriniz gibi cihazınızda saklanan kişisel profil bilgilerini okuma izni verir. Bu izin, uygulamanın sizi tanımlayabileceği ve profil bilgilerinizi başkalarına gönderebileceği anlamına gelir."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"kendi kişi kartınızı değiştirme"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Uygulamaya adınız ve iletişim bilgileriniz gibi cihazınızda saklanan kişisel profil bilgilerini değiştirme veya bunlara ekleme yapma izni verir. Bu izin, uygulamanın sizi tanımlayabileceği ve profil bilgilerinizi başkalarına gönderebileceği anlamına gelir."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"vücut sensörleri (kalp atış hızı takip cihazları gibi)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Uygulamanın, nabzınız gibi fiziksel durumunuzu izleyen sensörlerin gönderdiği verilere erişmesine izin verir."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosyal akışınızı okuma"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Uygulamaya size veya arkadaşlarınıza ait sosyal güncellemelere erişme ve bunları senkronize etme izni verir. Bilgi paylaşırken dikkatli olun. Bu izin, uygulamanın sosyal ağlarda sizinle arkadaşlarınız arasındaki iletişimi, gizliliğine bakılmaksızın okumasına olanak sağlar. Not: Bu izin tüm sosyal ağlar için geçerli olmayabilir."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosyal akışınıza yazma"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Uygulamaya arkadaşlarınızın sosyal güncellemelerini gösterme izni verir. Bilgi paylaşırken dikkatli olun -- Bu uygulama bir arkadaşınızdan geliyormuş gibi görünen iletiler oluşturabilir. Not: Bu izin, tüm sosyal ağlarda geçerli olmayabilir."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"takvim etkinliklerini ve gizli bilgileri oku"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Uygulamaya, arkadaşlarınızın ve iş arkadaşlarınızın etkinlikleri de olmak üzere tabletinizde depolanan tüm takvim etkinliklerini okuma izni verir. Bu izin, uygulamanın takvim verilerinizi gizliliğine ve hassaslığına bakmaksızın paylaşmasına ve kaydetmesine olanak sağlayabilir."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Uygulamaya, arkadaşlarınızın ve iş arkadaşlarınızın etkinlikleri dahil olmak üzere TV\'nizde kayıtlı tüm takvim etkinliklerini okuma izni verir. Bu da uygulamanın gizlilik ve duyarlılık dikkate alınmaksızın takvim verilerinizi paylaşmasına veya kaydetmesine olanak sağlayabilir."</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Uygulamaya bir hesaba ait senkronizasyon ayarlarını değiştirme izni verir. Örneğin, bu izne sahip bir uygulama Kişiler uygulamasının bir hesapla senkronize edilmesini etkinleştirebilir."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"senk. istatistiklerini okuma"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Uygulamaya bir hesaba ait senkronizasyon istatistiklerini okuma izni verir. Buna senkronizasyon etkinlikleri geçmişi ve senkronize edilen veri miktarı bilgileri de dahildir."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"sözlüğe eklediğiniz terimleri okuma"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Uygulamaya, kullanıcının kullanıcı sözlüğünde depolamış olabileceği kelimeleri, adları ve kelime öbeklerini okuma izni verir."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"kullanıcı tanımlı sözlüğe kelime ekleme"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Uygulamaya, kullanıcı sözlüğüne yeni kelimeler yazma izni verir."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB belleğini okuma"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD kartımın içeriğini oku"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Uygulamaya, USB depolama biriminizin içeriğini okuma izni verir."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 61e487c..0d23acd 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,32 +226,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Геодані"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"доступ до геоданих пристрою"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Соціальна інформація"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Безпосередній доступ до інформації про ваші контакти та соціальні зв’язки."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"отримувати доступ до календаря"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"надсилати та переглядати SMS-повідомлення"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Зберігання"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"отримувати доступ до фотографій, мультимедійного вмісту та файлів на вашому пристрої"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Словник користувача"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Переглядати або додавати слова в словнику користувача."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Закладки й історія"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Безпосередній доступ до закладок та історії веб-переглядача."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Мікрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"записувати аудіо"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографувати та записувати відео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"телефонувати та керувати дзвінками"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"отримувати доступ до інформації про ваші життєві показники та фізичну активність"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Датчики на тілі"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"отримувати доступ до інформації датчиків про ваші життєві показники"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Отримувати вміст вікна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Перевіряти вміст вікна, з яким ви взаємодієте."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Увімкнути функцію дослідження дотиком"</string>
@@ -335,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дозволяє програмі змінювати журнал викликів вашого планшетного ПК, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Додаток може змінювати журнал викликів телевізора, зокрема дані про вхідні та вихідні дзвінки. Шкідливі додатки можуть використовувати це, щоб стирати чи змінювати ваш журнал викликів."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дозволяє програмі змінювати журнал викликів вашого телефону, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"читати картки контактів"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Дозволяє програмі читати особисту інформацію профілю, збережену на пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що програма може ідентифікувати вашу особу та надсилати дані вашого профілю іншим."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"змінювати картки контактів"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Дозволяє програмі змінювати чи додавати особисту інформацію профілю, збережену на пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що програма може ідентифікувати вашу особу та надсилати дані вашого профілю іншим."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"датчики на тілі (як-от пульсометр)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Додаток має доступ до даних із датчиків, які відстежують фізичний стан, зокрема пульс."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читати ваш соціальний потік"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Дозволяє програмі отримувати доступ до оновлень із соціальних мереж від вас і ваших друзів та синхронізувати їх. Будьте обережні, надаючи доступ до інформації – це дозволяє програмі читати повідомлення, якими ви та ваші друзі обмінювалися в соціальних мережах, незалежно від конфіденційності. Зауважте: цей дозвіл не можна застосовувати в усіх соціальних мережах."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писати у ваш соціальний потік"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Дозволяє програмі відображати оновлення із соціальних мереж від ваших друзів. Будьте обережні, надаючи доступ до інформації – це дозволяє програмі створювати повідомлення, які надходять ніби від друга. Зауважте: цей дозвіл не можна застосовувати в усіх соціальних мережах."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"читати події календаря, а також конфіденційну інформацію"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Дозволяє програмі читати всі події календаря, збережені в планшетному ПК, включно з подіями друзів або співробітників. Це може дозволити програмі надсилати або зберігати дані календаря, незалежно від конфіденційності або закритості."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Додаток може читати всі події календаря, збережені в телевізорі, зокрема події друзів або співробітників. Завдяки цьому додаток може надсилати або зберігати дані календаря, незалежно від їх конфіденційності або закритості."</string>
@@ -457,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Дозволяє програмі змінювати налаштування синхронізації для облікового запису, наприклад, вмикати синхронізацію програми Люди з обліковим записом."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Перегляд статистики синхронізації"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Дозволяє програмі читати статистику синхронізації облікового запису, зокрема історію синхронізацій і обсяг синхронізованих даних."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"читати додані в словник терміни"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Дозволяє програмі читати всі слова, назви та фрази, які користувач міг зберегти у своєму словнику."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"додавати слова у вказаний користувачем словник"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дозволяє програмі писати нові слова в словник користувача."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"читати вміст носія USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"читати вміст карти SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Дозволяє програмі читати вміст носія USB."</string>
@@ -731,7 +712,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..ce3f2de 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,40 +224,35 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"مقام"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"اس آلہ کے مقام تک رسائی حاصل کریں"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"آپ کی سوشل معلومات"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"اپنے رابطوں اور سوشل کنکشنز کے بارے میں معلومات تک براہ راست رسائی۔"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"کیلنڈر"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS پیغامات بھیجیں اور دیکھیں"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"اسٹوریج"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"اپنے آلہ پر تصاویر، میڈیا اور فائلوں تک رسائی حاصل کریں"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"صارف کی لغت"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"صارف کی لغت میں الفاظ پڑھیں یا لکھیں۔"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"بُک مارکس اور سرگزشت"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"بک مارکس اور براؤزر کی سرگزشت تک براہ راست رسائی۔"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"مائکروفون"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"آڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"کیمرا"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"تصاویر لیں اور ویڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"فون"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"فون کالز کریں اور ان کا نظم کریں"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"سینسرز"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"اپنی علاماتِ حیات اور جسمانی سرگرمی بارے معلومات تک رسائی حاصل کریں"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"اپنی علامات حیات کے متعلق سنسر ڈیٹا تک رسائی حاصل کریں"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ونڈو مواد بازیافت کرنے کی"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسے ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسی ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ٹچ کے ذریعے دریافت کریں کو آن کریں"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"ٹچ کیے ہوئے آئٹمز کو زور سے بولا جائے گا اور اشاروں کا استعمال کرکے اسکرین کو دریافت کیا جا سکتا ہے۔"</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"بہتر ویب accessibility کو آن کریں"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ایپ کا مواد مزید قابل رسائی بنانے کیلئے اسکرپٹس کو انسٹال کیا جا سکتا ہے۔"</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"آپکے ٹائپ کردہ متن کا مشاہدہ کرنے کی"</string>
- <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"کریڈٹ کارڈ نمبرز اور پاس ورڈز جیسے ذاتی ڈیٹا پر مشتمل ہوتا ہے۔"</string>
+ <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"اس میں ذاتی ڈیٹا جیسے کریڈٹ کارڈ نمبرز اور پاس ورڈز شامل ہیں۔"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"حیثیت بار"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ایپ کو آپ کے ٹیبلٹ کی کال لاگ، بشمول آنے والی اور باہر جانے والی کالوں کے بارے میں ڈیٹا میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کرسکتی ہیں۔"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"انکمنگ اور آؤٹ گوئنگ کالز کے بارے میں ڈیٹا سمیت، ایپ کو آپ کے TV کے کال لاگ میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کرسکتی ہیں۔"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ایپ کو آپ کے فون کی کال لاگ، بشمول آنے والی اور باہر جانے والی کالوں کے بارے میں ڈیٹا میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کرسکتی ہیں۔"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"خود اپنا رابطہ کارڈ پڑھیں"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ایپ کو آپ کے آلے پر اسٹور کردہ ذاتی پروفائل کی معلومات، جیسے آپ کا نام اور رابطہ کی معلومات پڑھنے کی اجازت دیتا ہے۔ اس کا مطلب یہ ہے کہ ایپ آپ کی نشاندہی کرسکتی ہے اور آپ کے پروفائل کی معلومات دوسروں کو بھیج سکتی ہے۔"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"اپنے رابطہ کارڈ میں ترمیم کریں"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ایپ کو آپ کے آلے پر اسٹور کردہ ذاتی پروفائل کی معلومات، جیسے آپ کا نام اور رابطے کی معلومات تبدیل یا اس میں شامل کرنے کی اجازت دیتا ہے۔ اس کا مطلب یہ ہے کہ ایپ آپ کی نشاندہی کرسکتی اور آپ کے پروفائل کی معلومات دوسروں کو بھیج سکتی ہے۔"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"باڈی سینسرز (جیسے دل کی دھڑکن کے مانیٹرز)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ان سینسرز سے ڈیٹا تک رسائی حاصل کرنے کی اجازت دیتی ہے جو آپ کی حرکت قلب کی شرح جیسی آپ کی فزیکل صورتحال کو مانیٹر کرتے ہیں۔"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"اپنا سوشل سلسلہ پڑھیں"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ایپ کو آپ اور آپ کے دوستوں کے سماجی اپ ڈیٹس تک رسائی حاصل کرنے اور انہیں مطابقت پذیر بنانے کی اجازت دیتا ہے۔ معلومات کا اشتراک کرتے وقت محتاط رہیں -- رازداری سے قطع نظر، یہ سماجی نیٹ ورکس پر آپ اور آپ کے دوستوں کے بیچ مواصلتوں کو پڑھنے کی اجازت دیتا ہے۔ نوٹ: یہ اجازت سبھی سماجی نیٹ ورکس پر نافذ نہیں کی جاسکتی ہے۔"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"اپنے سوشل سلسلہ میں لکھیں"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ایپ کو آپ کے دوستوں کی جانب سے سماجی اپ ڈیٹس کو ڈسپلے کرنے کی اجازت دیتا ہے. معلومات کا اشتراک کرتے وقت محتاط رہیں - یہ ایپ کو ایسے پیغامات تیار کرنے کی اجازت دیتا ہے جو کسی دوست کی جانب سے آئے ہوئے معلوم پڑسکتے ہیں۔ نوٹ: یہ اجازت سبھی سماجی نیٹ ورکس پر نافذ نہیں کی جاسکتی ہے۔"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"کیلنڈر ایونٹس کے ساتھ رازداری کی معلومات پڑھیں"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ایپ کو آپ کے، بشمول آپ کے دوستوں یا ساتھی کارکنان کے ٹیبلٹ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھنے کی اجازت دیتا ہے۔ یہ ایپ کو رازداری یا حساسیت سے قطع نظر آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کرنے کی اجازت دیتا ہے۔"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ایپ کو آپ کے TV پر اسٹور کردہ دوستوں اور ساتھی کارکنوں کے کیلنڈر ایونٹس سمیت، سبھی کیلنڈر ایونٹس کو پڑھنے کی اجازت دیتا ہے۔ رازداری یا حساسیت سے قطع نظر، یہ ایپ کو آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کرنے کی اجازت دے سکتا ہے۔"</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ایپ کو کسی اکاؤنٹ کیلئے مطابقت پذیری کی ترتیبات میں ترمیم کرنے کی اجازت دیتا ہے۔ مثلا، کسی اکاؤنٹ کے ساتھ People ایپ کی مطابقت پذیری فعال کرنے کیلئے اسے استعمال کیا جاسکتا ہے۔"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"مطابقت پذیری کے اعداد و شمار پڑھیں"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ایپ کو کسی اکاؤنٹ کیلئے مطابقت پذیری کے اعداد و شمار، بشمول مطابقت پذیری کے ایونٹس اور جس قدر ڈیٹا مطابقت پذیر ہے اس کی سرگزشت کو پڑھنے کی اجازت دیتا ہے۔"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"لغت میں اپنے ذریعہ شامل کردہ اصطلاحات کو پڑھیں"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"ایپ کو وہ سبھی الفاظ، نام اور فقرے پڑھنے کی اجازت دیتا ہے جو صارف نے صارف کی لغت میں محفوظ کیے ہو سکتے ہیں۔"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"صارف کے ذریعہ متعین کردہ لغت میں الفاظ شامل کریں"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ایپ کو صارف کی لغت میں نئے الفاظ لکھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"آپ USB سٹوریج کے مواد کو پڑھیں"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"اپنے SD کارڈ کے مواد کو پڑھیں"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"ایپ کو آپ کے USB اسٹوریج کے مواد کو پڑھنے کی اجازت دیتا ہے۔"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index e3eb789..10d7661 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Joylashuv"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"qurilmaning joylashuvi haqidagi ma’lumotlarga kirish"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ijtimoiy ma’lumotingiz"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktlaringiz va ijtimoiy aloqalaringiz haqidagi ma’lumotga to‘g‘ridan to‘g‘ri o‘tadi."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Taqvim"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvimga kirish"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS xabarlarni yuborish va ko‘rish"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Xotira"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"qurilmangizdagi rasm, media va fayllarga kirish"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Foydalanuvchi lug‘ati"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Foydalanuvchi lug‘atida so‘zlarni o‘qish yoki yozish"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Xatcho‘plar va tarix"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Xatcho‘plar va brauzer tarixiga to‘g‘ridan to‘g‘ri kirishga ruxsat."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ovoz yozib olish"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"rasm va videoga olish"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon qo‘ng‘iroqlarini amalga oshirish va boshqarish"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorlar"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"asosiy belgilaringiz va jismoniy faolligingiz haqidagi ma’lumotlarga kirish"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Tana sezgichlari"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"asosiy belgilaringiz haqidagi sezgich ma’lumotlariga kirish"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Oynadagi kontentni o‘qiydi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Tegib o‘rganish xizmatini yoqish"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ilovaga planshetingizdagi qo‘ng‘iroq jurnallari, kiruvchi va chiquvchi qo‘ng‘rioqlar haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Zararli ilovalar bundan qo‘ng‘iroqlar jurnalini o‘zgartirish yoki o‘chirish uchun foydalanishi mumkin."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ilovaga televizoringizdagi qo‘ng‘iroqlar jurnali, kirish va chiqish qo‘ng‘rioqlari haqidagi ma’lumotlarni o‘zgartirish huquqini beradi. Zararli ilovalar undan qo‘ng‘iroqlar jurnalini o‘zgartirish yoki o‘chirish uchun foydalanishi mumkin."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ilovaga telefoningizdagi qo‘ng‘iroq jurnallari, kiruvchi va chiquvchi qo‘ng‘rioqlar haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Zararli ilovalar bundan qo‘ng‘iroqlar jurnalini o‘zgartirish yoki o‘chirish uchun foydalanishi mumkin."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"shaxsiy kontaktlar kartangizni o‘qish"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ilovaga ismingiz va aloqa ma’lumotlari kabi qurilmangizga zaxiralangan shaxsiy profil ma’lumotlaringizni o‘qish uchun ruxsat beradi. Bu ilova sizni tanib olishi va profil ma’lumotlaringizni boshqalarga jo‘natishi mumkinligini bildiradi."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"shaxsiy kontaktlar kartangizni o‘zgartirish"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ilovaga qurilmangizga zaxiralangan ismingiz va aloqa ma’lumotlaringiz kabi shaxsiy profillingiz ma’lumotlarini o‘zgartirish yoki ularga ma’lumot qo‘shish imkonini beradi. Bu ilova sizni tanib olishi va profil ma’lumotlaringizni boshqalarga jo‘natishi mumkinligini bildiradi."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"sezgichlar (m-n, yurak urishi)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ilovaga sezgichlardan olingan jismoniy holatingiz haqidagi ma’lumotlarni, masalan, yurak urishini kuzatish uchun ruxsat beradi."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ijtimoiy uzatishni o‘qish"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ilovaga siz va do‘stlaringizning ijtimoiy tarmoqlaridagi yangiliklarga kirish va ularni sinxronlashga ruxsat beradi. Ma’lumot ulashayotganda ehtiyot bo‘ling -- u ilovaga ijtimoiy tarmoqlarda maxfiyligidan qat’iy nazar siz va do‘stlaringiz o‘rtasidagi yozishmalarni o‘qish imkonini beradi. Diqqat qiling: ushbu ruxsat na barcha ijtimoiy tarmoqlarda talab qilinishi mumkin."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ijtimoiy uzatishga yozish"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Ilovaga do‘stlaringizning ijtimoiy tarmoqlardagi yangiliklarini ko‘rsatishiga ruxsat beradi. Ma’lumot ulashayotganda ehtiyot bo‘ling -- u ilovaga go‘yoki do‘stlardan kelgan xabarlarni yaratishga imkon beradi. Diqqat qiling: ushbu ruxsat na barcha ijtimoiy tarmoqlarda talab qilinishi mumkin."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"taqvimdagi tadbirlarni maxfiy ma’lumotlari bilan birga o‘qish"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ilovaga planshetingizda joylashgan va do‘stlaringiz yoki hamkasblaringiz tomonidan qo‘shilgan barcha taqvim tadbirlarini o‘qishga ruxsat beradi. Bu ilovaga maxfiyligi va muhimligidan qat’iy nazar taqvim ma’lumotlaringizni ulashish yoki saqlashga ruxsat berishi mumkin."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ilovaga televizoringizga saqlangan barcha taqvim tadbirlarini, jumladan, do‘stlaringiz yoki hamkasblaringiz tomonidan yaratilgan tadbirlarni o‘qish huquqini beradi. Bu ilovaga taqvimingizdagi ma’lumotlarni, ularning maxfiyligi yoki ta’sirchanligidan qat’i nazar, o‘ziga saqlash yoki boshqalarga ulashish huquqini berishi mumkin."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ilovaga hisobning sinxronlash sozlamalarini o‘zgartirish uchun ruxsat beradi. Masalan, bundan \"Odamlar\" ilovasini hisob bilan sinxronlanlash uchun foydalanish mumkin."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"sinxronlash statistikasini o‘qish"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ilovaga hisobning sinxronlash statistikasini, shu jumladan, sinxronlangan hodisalar tarixi va qancha ma’lumot sinxronlanganligi haqidagi ma’lumotni o‘qishga ruxsat beradi."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"lug‘atga qo‘shgan atamalaringizni o‘qish"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Ilovaga foydalanuvchi lug‘atga zaxiralagan barcha so‘zlar, nomlar va so‘z birikmalarini o‘qish uchun ruxsat beradi."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"foydalanuvchi lug‘atiga so‘zlar qo‘shish"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ilova yangi so‘zlarni foydalanuvchi lug‘atiga kiritishi mumkin."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"USB xotirasi tarkibidagilarni o‘qish"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"SD xotira kartasi tarkibidagilarni o‘qish"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Dasturga USB xotiradagi ma’lumotlarini ko‘rib chiqish uchun ruxsat beradi."</string>
@@ -729,7 +710,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..93994b6 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vị trí"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"truy cập vị trí của thiết bị này"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Thông tin xã hội của bạn"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Truy cập trực tiếp vào thông tin về các địa chỉ liên hệ và các kết nối xã hội của bạn."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Lịch"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"truy cập lịch của bạn"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Tin nhắn SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"gửi và xem tin nhắn SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Bộ nhớ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"truy cập ảnh, phương tiện và tệp trên thiết bị của bạn"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Từ điển người dùng"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Đọc hoặc viết các từ trong từ điển người dùng."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Dấu trang và lịch sử"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Truy cập trực tiếp vào dấu trang và lịch sử trình duyệt."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrô"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ghi âm"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Máy ảnh"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"chụp ảnh và quay video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Điện thoại"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"thực hiện và quản lý cuộc gọi điện thoại"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Cảm biến"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"truy cập thông tin về các dấu hiệu quan trọng và hoạt động thể chất của bạn"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Cảm biến cơ thể"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"truy cập dữ liệu cảm biến về dấu hiệu sinh tồn của bạn"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Truy xuất nội dung cửa sổ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kiểm tra nội dung của cửa sổ bạn đang tương tác."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Bật Khám phá bằng cách chạm"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên máy tính bảng của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên TV của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên điện thoại của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"đọc thẻ liên hệ của riêng bạn"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Cho phép ứng dụng đọc thông tin tiểu sử cá nhân được lưu trữ trên thiết bị, chẳng hạn như tên và thông tin liên hệ của bạn. Điều này có nghĩa là ứng dụng có thể xác định danh tính của bạn và gửi thông tin tiểu sử của bạn cho người khác."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"sửa đổi thẻ liên hệ của riêng bạn"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Cho phép ứng dụng thay đổi hoặc thêm vào thông tin tiểu sử cá nhân được lưu trữ trên thiết bị, chẳng hạn như tên và thông tin liên hệ của bạn. Điều này có nghĩa là ứng dụng có thể xác định danh tính của bạn và gửi thông tin tiểu sử của bạn cho người khác."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"cảm biến cơ thể (như máy đo nhịp tim)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Cho phép ứng dụng truy cập dữ liệu từ bộ cảm biến giám sát tình trạng sức khỏe của bạn, ví dụ như nhịp tim."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"đọc luồng xã hội của bạn"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Cho phép ứng dụng truy cập và đồng bộ hóa các cập nhật xã hội của bạn và bạn bè bạn. Hãy cẩn trọng khi chia sẻ thông tin -- việc này có thể cho phép ứng dụng đọc thông tin liên lạc giữa bạn và bạn bè bạn trên các mạng xã hội, bất kể tính bí mật là gì. Lưu ý: quyền này có thể không được thực thi trên tất cả các mạng xã hội."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ghi luồng xã hội của bạn"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Cho phép ứng dụng hiển thị các cập nhật xã hội từ bạn bè của bạn. Hãy cẩn trọng khi chia sẻ thông tin -- việc này có thể cho phép ứng dụng tạo tin nhắn dường như đến từ một người bạn. Lưu ý: quyền này có thể không được thực thi trên tất cả các mạng xã hội."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"đọc các sự kiện lịch và thông tin bí mật"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Cho phép ứng dụng đọc tất cả các sự kiện trên lịch được lưu trữ trên máy tính bảng của bạn, bao gồm các sự kiện trên lịch của bạn bè hoặc đồng nghiệp. Việc này có thể cho phép ứng dụng chia sẻ hoặc lưu dữ liệu lịch của bạn, bất kể tính bí mật hay tính nhạy cảm là gì."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Cho phép ứng dụng đọc tất cả các sự kiện trên lịch được lưu trữ trên TV của bạn, bao gồm các sự kiện trên lịch của bạn bè hoặc đồng nghiệp. Việc này có thể cho phép ứng dụng chia sẻ hoặc lưu dữ liệu lịch của bạn, bất kể mức độ bảo mật hay mức độ nhạy cảm."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Cho phép ứng dụng sửa đổi cài đặt đồng bộ hóa cho tài khoản. Ví dụ: ứng dụng có thể được sử dụng để cho phép đồng bộ hóa ứng dụng Mọi người với tài khoản."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"đọc thống kê đồng bộ hóa"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Cho phép ứng dụng đọc thống kê đồng bộ hóa cho tài khoản, bao gồm lịch sử của các sự kiện đồng bộ hóa và lượng dữ liệu được đồng bộ hóa."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"đọc cụm từ bạn đã thêm vào từ điển"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Cho phép ứng dụng đọc tất cả các từ, tên và cụm từ mà người dùng có thể đã lưu trữ trong từ điển của người dùng."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"thêm từ vào từ điển do người dùng xác định"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Cho phép ứng dụng ghi từ mới vào từ điển của người dùng."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"đọc nội dung của bộ lưu trữ USB của bạn"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"đọc nội dung của thẻ SD của bạn"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Cho phép ứng dụng đọc nội dung của bộ lưu trữ USB."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index a7b4344..2322a4e 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,32 +224,28 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"使用此设备的位置信息"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交信息"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接访问与您的联系人和社交人脉相关的信息。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"短信"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"发送和查看短信"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"存储空间"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"访问您设备上的照片、媒体内容和文件"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"用户字典"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"读取用户字典中的字词或写入新字词。"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"书签和历史记录"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接访问书签和浏览器历史记录。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麦克风"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"录制音频"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相机"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍摄照片和录制视频"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"电话"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"拨打电话和管理通话"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"传感器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"访问与您的生命体征和健身运动相关的信息"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_sensors (7147968539346634043) -->
+ <skip />
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"检索窗口内容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"检查您正与其进行互动的窗口的内容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"启用触摸浏览"</string>
@@ -333,16 +328,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允许该应用修改平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"允许应用修改电视的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允许该应用修改手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"读取您自己的名片"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"允许该应用读取您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着该应用可以识别您的身份,并可能将您的个人资料信息发送给他人。"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"修改您自己的名片"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允许该应用更改或添加您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着该应用可以识别您的身份,并可能将您的个人资料信息发送给他人。"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"人体传感器(如心跳速率检测器)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允许该应用存取监测您身体状况的传感器所收集的数据,例如您的心率。"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"读取您的社交信息流"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允许该应用访问并同步您和朋友的社交动态信息。在分享信息时一定要小心,因为此权限可让该应用读取您与社交网络上的朋友之间的交流信息。"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"写入您的社交信息流"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"允许该应用显示您朋友的社交动态信息。在分享信息时一定要小心,因为此权限可让该应用冒充某个朋友编写消息。请注意:此权限可能不适用于所有社交网络。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"读取日历活动和机密信息"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"允许该应用读取您平板电脑上存储的所有日历活动,包括朋友或同事的活动。此权限可让该应用分享或保存您的日历数据,而不论这些数据是否属于机密或敏感内容。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"允许应用读取您的电视上存储的所有日历活动,包括朋友或同事的活动。此权限可让应用分享或保存您的日历数据,而不论这些数据是否属于机密或敏感内容。"</string>
@@ -455,10 +442,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允许该应用修改某个帐户的同步设置。例如,此权限可用于在“联系人”应用与某个帐户之间启用同步。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"读取同步统计信息"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"允许该应用读取某个帐户的同步统计信息,包括同步活动历史记录和同步数据量。"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"读取您添加到字典的字词"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"允许该应用读取用户可能已在用户字典中存储的所有字词、名称和词组。"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"向用户定义的字典添加字词"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允许应用向用户字典中写入新词。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"读取您的USB存储设备中的内容"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"读取您的SD卡中的内容"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"允许应用读取您USB存储设备中的内容。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 097acfa..88667c9 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"存取此裝置的位置"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交資訊"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接存取您的聯絡人資訊和社交網站資訊。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取您的日曆"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"短訊"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"傳送和查看短訊"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"儲存空間"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"在您的裝置上存取相片、媒體和檔案"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"使用者字典"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"讀取或寫入使用者字典中的字詞。"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"書籤和記錄"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接存取書籤和瀏覽器紀錄。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄製語音訊息"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照和錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"存取與您的生命體徵和身體活動相關的資料"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取與您生命體徵相關的感應器資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您使用中的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"開啟「輕觸探索」功能"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"允許應用程式修改電視的通話記錄,包括來電和撥出電話的相關資料。惡意應用程式可能會藉此清除或修改您的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"讀取自己的聯絡資料"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"允許應用程式讀取裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身份,並將您的個人資料傳送給他人。"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"修改自己的聯絡資料"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允許應用程式新增或更改裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身份,並將您的個人資料傳送給他人。"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"身體感應器 (例如心跳監視器)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允許應用程式存取感應器所收集的資料 (這類感應器可監測您的體能狀態,例如您的心跳速率)。"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允許應用程式存取並同步處理您和好友的最新動態。當您分享資訊時,請務必小心,因為這項權限允許應用程式讀取您和好友在社交網絡上的私人通訊,不論是否機密。注意:這項權限可能不適用於所有社交網絡。"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"允許應用程式顯示好友的最新動態。當您分享資訊時,請務必小心,因為這項權限讓應用程式可偽裝好友產生訊息。注意:這項權限可能不適用於所有社交網絡。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"讀取日曆活動與機密資訊"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"允許應用程式讀取平板電腦上儲存的所有日曆活動,包括好友或同事的活動。如此一來,應用程式或可不論資料是否機密或敏感,自行共用或儲存您的日曆資料。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"允許應用程式讀取儲存在電視中的所有日曆活動,包括好友或同事的活動。這可能允許應用程式分享或儲存您的日曆資料 (不論是否機密或敏感資料)。"</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允許應用程式修改帳戶的同步設定,例如讓「通訊錄」應用程式與某個帳戶保持同步。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"讀取同步處理統計資料"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"允許應用程式讀取帳戶的同步統計資料,包括同步活動記錄,以及保持同步的資料量。"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"讀取加入字典中的字詞"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"允許應用程式讀取使用者儲存在使用者字典中的所有字詞、名稱和詞組。"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"將字詞加入使用者定義字典"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允許應用程式將新字詞寫入使用者字典。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"讀取您 USB 儲存裝置中的內容"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"讀取您 SD 記憶卡中的內容"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"允許應用程式讀取 USB 儲存裝置的內容。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a64ff187..de8cdde8 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,32 +224,27 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"存取這台裝置的位置資訊"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交資訊"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接存取您的聯絡人資訊與社交網站資訊。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取您的日曆"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"簡訊"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"傳送及查看簡訊"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"儲存"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"存取裝置中的相片、媒體和檔案"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"使用者字典"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"讀取使用者字典中的字詞或寫入新字詞"</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"書籤與紀錄"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接存取書籤和瀏覽器紀錄。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄音"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照及錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"存取生命徵象和體能活動的相關資訊"</string>
+ <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
+ <skip />
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取生命徵象的相關感應器資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您存取的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"啟用輕觸探索功能"</string>
@@ -333,16 +327,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允許應用程式修改平板電腦的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改您的通話紀錄。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"允許應用程式修改電視的通話紀錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此清除或修改您的通話紀錄。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允許應用程式修改手機的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改您的通話紀錄。"</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"讀取自己的聯絡資訊"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"允許應用程式讀取裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身分,並將您的個人資料傳送給他人。"</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"修改自己的聯絡資訊"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允許應用程式新增或變更裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這項設定可讓應用程式識別您的身分,並可能將您的個人資料傳送給他人。"</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"身體感應器 (例如心律監測器)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允許應用程式存取感測器所收集的資料 (這類感測器可監測您的體能狀態,例如您的心跳速率)。"</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允許應用程式存取並同步處理您和好友的最新動態。因此,當您分享資訊時請小心,因為這項權限可讓應用程式讀取您和好友在社交網路上的私人通訊,包括機密通訊。注意:並非所有社交網路皆適用於這項權限。"</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"允許應用程式顯示好友的最新動態。因此,當您分享資訊時請小心,因為這項權限可讓應用程式偽裝好友產生訊息。注意:並非所有社交網路皆適用於這項權限。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"讀取日曆活動與機密資訊"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"允許應用程式讀取平板電腦上儲存的所有日曆活動,包括好友或同事的活動。這項設定會讓應用程式共用或儲存您的日曆資料,甚至包括機密或敏感的資料。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"允許應用程式讀取所有儲存在電視上的日曆活動,包括好友或同事的活動。應用程式可能會藉此洩漏或儲存您的日曆資料 (不論是否為機密或敏感資料)。"</string>
@@ -455,10 +441,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允許應用程式修改帳戶的同步處理設定,例如讓「使用者」應用程式與某個帳戶進行同步處理。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"讀取同步處理狀態"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"允許應用程式讀取帳戶的同步處理統計資料,包括同步處理活動紀錄,以及同步處理的資料量。"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"讀取您加入字典的字詞"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"允許應用程式讀取使用者儲存在使用者字典內的所有字詞、名稱和詞組。"</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"將字詞加入使用者定義的字典"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允許應用程式將新字詞寫入使用者的字典。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"讀取 USB 儲存裝置的內容"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"讀取 SD 卡的內容"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"允許應用程式讀取 USB 儲存裝置的內容。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5794daf..355e746 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,32 +224,26 @@
<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>
<string name="permgrouplab_location" msgid="7275582855722310164">"Indawo"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"finyelela kundawo yale divayisi"</string>
- <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ulwazi lakho lomphakathi"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ukufinyelela okuqondile kulwazi mayelana noxhumana nabo bomphakathi."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Ikhalenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"finyelela kukhalenda yakho"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"I-SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"thumela uphinde ubuke imilayezo ye-SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Isitoreji"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"finyelela kuzithombe, imidiya, namafayela kudivayisi yakho"</string>
- <string name="permgrouplab_dictionary" msgid="8114410334955871144">"Isichazamazwi somsebenzisi"</string>
- <string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Funda noma bhala amagama kusichazamazwi somsebenzisi."</string>
- <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Amabhukhimakhi nomlando"</string>
- <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ukufinyelela okuqondile kumlando wamabhukimakhi nesiphequluli."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"I-Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekhoda ividiyo"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Ikhamela"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"thatha izithombe uphinde urekhode ividiyo"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Ifoni"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"yenza uphinde uphathe amakholi wefoni"</string>
- <string name="permgrouplab_sensors" msgid="7416703484233940260">"Izinzwa"</string>
- <string name="permgroupdesc_sensors" msgid="2280821510554029577">"finyelela kulwazi olumayelana nezimpawu zakho zempilo nomsebenzi womzimba"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"Izinzwa zomzimba"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"finyelela idatha yesizweli mayelana nezimpawu zakho ezibalulekile"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Thola okuqukethwe kwewindi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Hlola okuqukethwe kwewindi ohlanganyela nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vula ukuhlola ngokuthinta"</string>
@@ -333,16 +326,8 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ivumela uhlelo lokusebenza ukushintsha ilogi yekholi yethebulethi yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ivumela uhlelo lokusebenza ukuthi liguqule ilogi yekholi yakho ye-TV, okufaka idatha emayelana namakholi angenayo naphumayo. Izinhlelo zokusebenza ezinobungozi zingasebenzisa lokhu ukususa noma ukuguqula ilogi yakho yekholi."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ivumela uhlelo lokusebenza ukushintsha irekhodi lamakholi efoni yakho, kufaka phakathi idatha emayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"funda ikhadi lakho lokuxhumana"</string>
- <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ivumela uhlelo lokusebenza ukuthi lifunde ulwazi lephrofayela lomuntu siqu olugcinwe kudivayisi yakho njengegama lakho kanye nolwazi lokuxhumana. Lokhu kuchaza ukuthi uhlelo lokusebenza lingakuhlonza bese lithumelela abanye ulwazi lakho lephrofayela."</string>
- <string name="permlab_writeProfile" msgid="907793628777397643">"guqula ikhadi lakho lokuxhumana"</string>
- <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ivumela uhlelo lokusebenza ukushintsha noma ingeze ulwazi lomuntu siqu lwephrofayela olulondolozwe kudivayisi yakho, njengegama lakho kanye nolwazi lokuxhumana. Lokhu kuchaza ukuthi ezinye izinhlelo zokusebenza zingakuhlonza bese zithumelela abanye ulwazi lephrofayela yakho."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"izinzwa zomzimba (njengeziqaphi zokulinganisela inhliziyo)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kudatha kusukela kuzinzwa eziqapha isimo sakho somzimba, esifana nesilinganiso senhliziyo yakho."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"funda ngezindlela zakho zokuxhumana nabanye abantu"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ivumela uhlelo lokusebenza ukufinyelela nokuvumelanisa izibuyekezo zomphakathi ezivela kuwe nakubangani bakho. Qaphela uma waba ulwazi -- lokhu kuvumela uhlelo lokusebenza ukufunda ukuxhumana phakathi kwakho nabangani bakho kumanethiwekhi omphakathi, ngaphandle kokugcinwa kuyimfihlo. Qaphela: le mvume ingaphoqelelwa kuwo onke amanethiwekhi omphakathi."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"bhala indlela yakho yokuxhumana nabantu"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Ivumela uhlelo lokusebenza ukubonisa izibuyekezo zomphakathi ezivela kubangani bakho. Qaphela uma wabelana ngolwazi -- lokhu kuvumela uhlelo lokusebenza ukukhiqiza imilayezo engabonakala sengathi ivela kumngani. Qaphela: le mvume kungenzeka ingaphoqelelwa kuwo onke amanethiwekhi omphakathi."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"funda imicimbi yekhalenda kanye nokwaziswa okuyimfihlo"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ivumela uhlelo lokusebenza ukufunda zonke izehlakalo zekhalenda ezilondolozwe kuthebhulethi yakho, kufaka phakathi lezo zabangani noma osebenza nabo. Lokhu kungavumela uhlelo lokusebenza ukwabelana noma ukulondoloza idatha yakho yekhalenda, ngaphandle kokugcinwa kuyimfihlo noma ukuzwela."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ivumela uhlelo lokusebenza ukuthi lifunde yonke imicimbi yekhalenda egcinwe ku-TV yakho, efaka leyo yabangani noma osebenza nabo. Lokhu kungavumela uhlelo lokusebenza ukuthi labelane noma lilondoloze idatha yekhalenda yakho, ngokunganaki ubumfihlo noma ukuzwela."</string>
@@ -455,10 +440,6 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ivumela uhlelo lokusebenza ukushintsha izilungiselelo zokuvumelanisa ze-akhawunti. Isibonelo, lokhu kungasetshenziswa ukunika amandla ukuvumelanisa kohlelo lokusebenza le-People ne-akhawunti."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"funda izibalo zokuvumelanisa"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ivumela uhlelo lokusebenza ukufunda izibalo zokuvumelanisa ze-akhawunti, kufaka phakathi umlando wezehlakalo ezivumelanisiwe nokuthi ingakanani idatha evumelanisiwe."</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"funda imibandela oyengezile esichazimazwini"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Ivumela uhlelo lokusebenza ukufunda onke amabizo, amagama, namatemu umsebenzisi awalondolozile kusichazamazwi somsebenzisi."</string>
- <string name="permlab_writeDictionary" msgid="2183110402314441106">"engeza amagama kusichazamazwi ezichazwe umsebenzisi"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ivumela uhlelo lokusebenza ukuthi ibhale amagama amasha esichazinimazwi."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"funda okuqukethwe kokugciniwe kwakho okufinyeleleka nge-USD"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"funda okuqukethwe ekhadini lakho le-SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Ivumela uhlelo lokusebenza ukufunda okuqukethwe kwesitoreji sakho se-USB."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 33c9c60b..b1925ba 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -27,6 +27,9 @@
<!-- ============== -->
<eat-comment />
+ <!-- Specifies that a theme has a light background with dark text on top. -->
+ <attr name="isLightTheme" format="boolean" />
+
<!-- Default color of foreground imagery. -->
<attr name="colorForeground" format="color" />
<!-- Default color of foreground imagery on an inverted background. -->
@@ -3121,6 +3124,8 @@
<flag name="typeWindowsChanged" value="0x00400000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CONTEXT_CLICKED} events. -->
<flag name="typeContextClicked" value="0x00800000" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_ASSIST_READING_CONTEXT} events. -->
+ <flag name="typeAssistReadingContext" value="0x01000000" />
<!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPES_ALL_MASK} i.e. all events. -->
<flag name="typeAllMask" value="0xffffffff" />
</attr>
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 7272ae3..451813c 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>
@@ -1256,6 +1268,14 @@
application is desired. -->
<string name="default_sms_application" translatable="false">com.android.mms</string>
+ <!-- Default web browser. This is the package name of the application that will
+ be the default browser when the device first boots. Afterwards the user
+ can select whatever browser app they wish to use as the default.
+
+ If this string is empty or the specified package does not exist, then
+ the behavior will be as though no app was named as an explicit default. -->
+ <string name="default_browser" translatable="false"></string>
+
<!-- Enable/disable default bluetooth profiles:
HSP_AG, ObexObjectPush, Audio, NAP -->
<bool name="config_bluetooth_default_profiles">true</bool>
@@ -1831,6 +1851,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">
@@ -2031,10 +2064,8 @@
string that's stored in 8-bit unpacked format) characters.-->
<bool translatable="false" name="config_sms_decode_gsm_8bit_data">false</bool>
- <!-- List of package names (ordered by preference) providing WebView implementations. -->
- <string-array name="config_webViewPackageNames" translatable="false">
- <item>com.android.webview</item>
- </string-array>
+ <!-- Package name providing WebView implementation. -->
+ <string name="config_webViewPackageName" translatable="false">com.android.webview</string>
<!-- If EMS is not supported, framework breaks down EMS into single segment SMS
and adds page info " x/y". This config is used to set which carrier doesn't
@@ -2225,4 +2256,9 @@
(range of 18 - 21 kHz). -->
<bool name="config_supportSpeakerNearUltrasound">true</bool>
+ <!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
+ <bool name="config_eap_sim_based_auth_supported">true</bool>
+
+ <!-- How long history of previous vibrations should be kept for the dumpsys. -->
+ <integer name="config_previousVibrationsDumpLimit">20</integer>
</resources>
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/public.xml b/core/res/res/values/public.xml
index 65fa36b..ab798bb 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2631,27 +2631,41 @@
<public type="attr" name="fullBackupContent" />
<public type="style" name="Widget.Material.Button.Colored" />
- <public type="style" name="Theme.Material.DayNight" />
- <public type="style" name="Theme.Material.DayNight.DarkActionBar" />
- <public type="style" name="Theme.Material.DayNight.Dialog" />
- <public type="style" name="Theme.Material.DayNight.Dialog.Alert" />
- <public type="style" name="Theme.Material.DayNight.Dialog.MinWidth" />
- <public type="style" name="Theme.Material.DayNight.Dialog.NoActionBar" />
- <public type="style" name="Theme.Material.DayNight.Dialog.NoActionBar.MinWidth" />
- <public type="style" name="Theme.Material.DayNight.Dialog.Presentation" />
- <public type="style" name="Theme.Material.DayNight.DialogWhenLarge" />
- <public type="style" name="Theme.Material.DayNight.DialogWhenLarge.NoActionBar" />
- <public type="style" name="Theme.Material.DayNight.NoActionBar" />
- <public type="style" name="Theme.Material.DayNight.NoActionBar.Fullscreen" />
- <public type="style" name="Theme.Material.DayNight.NoActionBar.Overscan" />
- <public type="style" name="Theme.Material.DayNight.NoActionBar.TranslucentDecor" />
- <public type="style" name="Theme.Material.DayNight.Panel" />
+
+ <style name="__reserved8" />
+ <public type="style" name="__reserved8" />
+ <style name="__reserved9" />
+ <public type="style" name="__reserved9" />
+ <style name="__reserved10" />
+ <public type="style" name="__reserved10" />
+ <style name="__reserved11" />
+ <public type="style" name="__reserved11" />
+ <style name="__reserved12" />
+ <public type="style" name="__reserved12" />
+ <style name="__reserved13" />
+ <public type="style" name="__reserved13" />
+ <style name="__reserved14" />
+ <public type="style" name="__reserved14" />
+ <style name="__reserved15" />
+ <public type="style" name="__reserved15" />
+ <style name="__reserved16" />
+ <public type="style" name="__reserved16" />
+ <style name="__reserved17" />
+ <public type="style" name="__reserved17" />
+ <style name="__reserved18" />
+ <public type="style" name="__reserved18" />
+ <style name="__reserved19" />
+ <public type="style" name="__reserved19" />
+ <style name="__reserved20" />
+ <public type="style" name="__reserved20" />
+ <style name="__reserved21" />
+ <public type="style" name="__reserved21" />
+ <style name="__reserved22" />
+ <public type="style" name="__reserved22" />
<public type="style" name="Theme.Material.Light.LightStatusBar" />
<public type="style" name="ThemeOverlay.Material.Dialog" />
<public type="style" name="TextAppearance.Material.Widget.Button.Inverse" />
<public type="style" name="ThemeOverlay.Material.Dialog.Alert" />
- <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
- <public type="style" name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" />
<public type="id" name="pasteAsPlainText" />
<public type="id" name="undo" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ea0d349..5288fa3 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. -->
@@ -599,9 +584,9 @@
<string name="permgroupdesc_phone">make and manage phone calls</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_sensors">Sensors</string>
+ <string name="permgrouplab_sensors">Body Sensors</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_sensors">access information about your vital signs and physical activity</string>
+ <string name="permgroupdesc_sensors">access sensor data about your vital signs</string>
<!-- Title for the capability of an accessibility service to retrieve window content. -->
<string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
@@ -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 4160e0e..01ecba8 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -240,6 +240,7 @@
<java-symbol type="attr" name="windowFixedHeightMajor" />
<java-symbol type="attr" name="windowFixedHeightMinor" />
<java-symbol type="attr" name="accessibilityFocusedDrawable"/>
+ <java-symbol type="attr" name="isLightTheme"/>
<java-symbol type="bool" name="action_bar_embed_tabs" />
<java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
@@ -251,6 +252,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" />
@@ -901,6 +903,7 @@
<java-symbol type="string" name="sipAddressTypeOther" />
<java-symbol type="string" name="sipAddressTypeWork" />
<java-symbol type="string" name="default_sms_application" />
+ <java-symbol type="string" name="default_browser" />
<java-symbol type="string" name="sms_control_message" />
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
@@ -1127,6 +1130,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 +1651,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" />
@@ -1703,6 +1708,7 @@
<java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
<java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
<java-symbol type="integer" name="config_notificationServiceArchiveSize" />
+ <java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
<java-symbol type="integer" name="config_radioScanningTimeout" />
<java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
@@ -2018,7 +2024,7 @@
<java-symbol type="attr" name="actionModeWebSearchDrawable" />
<java-symbol type="string" name="websearch" />
<java-symbol type="drawable" name="ic_media_video_poster" />
- <java-symbol type="array" name="config_webViewPackageNames" />
+ <java-symbol type="string" name="config_webViewPackageName" />
<!-- From SubtitleView -->
<java-symbol type="dimen" name="subtitle_corner_radius" />
@@ -2314,4 +2320,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" />
+ <java-symbol type="bool" name="config_eap_sim_based_auth_supported" />
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b7acdd4..c230645 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -42,6 +42,7 @@
-->
<style name="Theme">
+ <item name="isLightTheme">false</item>
<item name="colorForeground">@color/bright_foreground_dark</item>
<item name="colorForegroundInverse">@color/bright_foreground_dark_inverse</item>
<item name="colorBackground">@color/background_dark</item>
@@ -472,6 +473,7 @@
background will be a light color.
<p>This is designed for API level 10 and lower.</p>-->
<style name="Theme.Light">
+ <item name="isLightTheme">true</item>
<item name="windowBackground">@drawable/screen_background_selector_light</item>
<item name="windowClipToOutline">false</item>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 295b453..9d3a7ef 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1281,7 +1281,7 @@
</style>
<!-- Default theme for Settings and activities launched from Settings. -->
- <style name="Theme.Material.Settings" parent="Theme.Material.DayNight.DarkActionBar">
+ <style name="Theme.Material.Settings" parent="Theme.Material.Light.DarkActionBar">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
@@ -1291,7 +1291,7 @@
</style>
<!-- Default theme for Settings and activities launched from Settings. -->
- <style name="Theme.Material.Settings.NoActionBar" parent="Theme.Material.DayNight.NoActionBar">
+ <style name="Theme.Material.Settings.NoActionBar" parent="Theme.Material.Light.NoActionBar">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
@@ -1299,42 +1299,40 @@
<item name="searchDialogTheme">@style/Theme.Material.Settings.SearchBar</item>
<item name="panelMenuListTheme">@style/Theme.Material.Settings.CompactMenu</item>
</style>
-
- <style name="Theme.Material.Settings.BaseDialog" parent="Theme.Material.DayNight.BaseDialog">
+ <style name="Theme.Material.Settings.BaseDialog" parent="Theme.Material.Light.BaseDialog">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
<style name="Theme.Material.Settings.Dialog" parent="Theme.Material.Settings.BaseDialog" />
- <style name="Theme.Material.Settings.Dialog.BaseAlert" parent="Theme.Material.DayNight.Dialog.BaseAlert">
+ <style name="Theme.Material.Settings.Dialog.BaseAlert" parent="Theme.Material.Light.Dialog.BaseAlert">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
<style name="Theme.Material.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.BaseAlert" />
- <style name="Theme.Material.Settings.DialogWhenLarge" parent="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar">
+ <style name="Theme.Material.Settings.DialogWhenLarge" parent="Theme.Material.Light.DialogWhenLarge.DarkActionBar">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
- <style name="Theme.Material.Settings.DialogWhenLarge.NoActionBar" parent="Theme.Material.DayNight.DialogWhenLarge.NoActionBar">
+ <style name="Theme.Material.Settings.DialogWhenLarge.NoActionBar" parent="Theme.Material.Light.DialogWhenLarge.NoActionBar">
+ <item name="colorPrimary">@color/material_blue_grey_900</item>
+ <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+ </style>
+ <style name="Theme.Material.Settings.Dialog.Presentation" parent="Theme.Material.Light.Dialog.Presentation">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
- <style name="Theme.Material.Settings.Dialog.Presentation" parent="Theme.Material.DayNight.Dialog.Presentation">
+ <style name="Theme.Material.Settings.SearchBar" parent="Theme.Material.Light.SearchBar">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
- <style name="Theme.Material.Settings.SearchBar" parent="Theme.Material.DayNight.SearchBar">
- <item name="colorPrimary">@color/material_blue_grey_900</item>
- <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
- </style>
-
- <style name="Theme.Material.Settings.CompactMenu" parent="Theme.Material.DayNight.CompactMenu">
+ <style name="Theme.Material.Settings.CompactMenu" parent="Theme.Material.Light.CompactMenu">
<item name="colorPrimary">@color/material_blue_grey_900</item>
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
</style>
diff --git a/core/res/res/values/themes_material_daynight.xml b/core/res/res/values/themes_material_daynight.xml
deleted file mode 100644
index 4ecca6b..0000000
--- a/core/res/res/values/themes_material_daynight.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?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.
--->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see themes_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-<resources>
-
- <!-- Material theme (day/night vesion) for activities. -->
- <style name="Theme.Material.DayNight" parent="Theme.Material.Light" />
-
- <!-- Variant of Material.DayNight that has a solid (opaque) action bar
- with an inverse color profile. The dark action bar sharply stands out against
- the light content (when applicable). -->
- <style name="Theme.Material.DayNight.DarkActionBar" parent="Theme.Material.Light.DarkActionBar" />
-
- <!-- Variant of Material.DayNight with no action bar. -->
- <style name="Theme.Material.DayNight.NoActionBar" parent="Theme.Material.Light.NoActionBar" />
-
- <!-- Variant of Material.DayNight that has no title bar and fills
- the entire screen. This theme
- sets {@link android.R.attr#windowFullscreen} to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.Fullscreen" parent="Theme.Material.Light.NoActionBar.Fullscreen" />
-
- <!-- Variant of Material.DayNight that has no title bar and fills
- the entire screen and extends into the display overscan region. This theme
- sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
- to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.Overscan" parent="Theme.Material.Light.NoActionBar.Overscan" />
-
- <!-- Variant of Material.DayNight that has no title bar and translucent
- system decor. This theme sets {@link android.R.attr#windowTranslucentStatus} and
- {@link android.R.attr#windowTranslucentNavigation} to true. -->
- <style name="Theme.Material.DayNight.NoActionBar.TranslucentDecor" parent="Theme.Material.Light.NoActionBar.TranslucentDecor" />
-
- <!-- Default Material.DayNight theme for panel windows. This removes all extraneous
- window decorations, so you basically have an empty rectangle in which
- to place your content. It makes the window floating, with a transparent
- background, and turns off dimming behind the window. -->
- <style name="Theme.Material.DayNight.Panel" parent="Theme.Material.Light.Panel" />
-
- <!-- Material theme (day/night vesion) for dialog windows and activities,
- which is used by the {@link android.app.Dialog} class. This changes
- the window to be floating (not fill the entire screen), and puts a
- frame around its contents. You can set this theme on an activity if
- you would like to make an activity that looks like a Dialog. -->
- <style name="Theme.Material.DayNight.Dialog" parent="Theme.Material.DayNight.BaseDialog" />
- <style name="Theme.Material.DayNight.BaseDialog" parent="Theme.Material.Light.BaseDialog" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that has a nice minimum width for
- a regular dialog. -->
- <style name="Theme.Material.DayNight.Dialog.MinWidth" parent="Theme.Material.Light.Dialog.MinWidth" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that does not include a title bar. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar" parent="Theme.Material.Light.Dialog.NoActionBar" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog.NoActionBar that has a nice minimum width for
- a regular dialog. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar.MinWidth" parent="Theme.Material.Light.Dialog.NoActionBar.MinWidth" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog that has a fixed size. -->
- <style name="Theme.Material.DayNight.Dialog.FixedSize" parent="Theme.Material.Light.Dialog.FixedSize" />
-
- <!-- Variant of Theme.Material.DayNight.Dialog.NoActionBar that has a fixed size. -->
- <style name="Theme.Material.DayNight.Dialog.NoActionBar.FixedSize" parent="Theme.Material.Light.Dialog.NoActionBar.FixedSize" />
-
- <!-- Theme for a window that will be displayed either full-screen on
- smaller screens (small, normal) or as a dialog on larger screens
- (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge" parent="Theme.Material.Light.DialogWhenLarge" />
-
- <!-- Theme for a window with a dark action bar that will be displayed
- either full-screen on smaller screens (small, normal) or as a dialog
- on larger screens (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" parent="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
-
- <!-- Theme for a window without an action bar that will be displayed either full-screen
- on smaller screens (small, normal) or as a dialog on larger screens
- (large, xlarge). -->
- <style name="Theme.Material.DayNight.DialogWhenLarge.NoActionBar" parent="Theme.Material.Light.DialogWhenLarge.NoActionBar" />
-
- <!-- Theme for a presentation window on a secondary display. -->
- <style name="Theme.Material.DayNight.Dialog.Presentation" parent="Theme.Material.Light.Dialog.Presentation" />
-
- <!-- Material user theme for alert dialog windows, which is used by the
- {@link android.app.AlertDialog} class. -->
- <style name="Theme.Material.DayNight.Dialog.Alert" parent="Theme.Material.DayNight.Dialog.BaseAlert" />
- <style name="Theme.Material.DayNight.Dialog.BaseAlert" parent="Theme.Material.Light.Dialog.BaseAlert" />
-
- <style name="Theme.Material.DayNight.SearchBar" parent="Theme.Material.Light.SearchBar" />
- <style name="Theme.Material.DayNight.CompactMenu" parent="Theme.Material.Light.CompactMenu" />
-
-</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 18c83b4..5783a49 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -92,12 +92,14 @@
<shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
<!-- 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}" />
+ http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
+ visual voicemail code for Orange: 21101 -->
+ <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}" />
+ http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
+ visual voicemail code for EE: 887 -->
+ <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]" />
@@ -183,7 +185,8 @@
<!-- Ukraine: 4 digits, known premium codes listed -->
<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" />
+ <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm),
+ visual voicemail code for T-Mobile: 122 -->
+ <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/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
index 6ee6ffa..6b3b55e 100644
--- a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
@@ -5,6 +5,4 @@
LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
-LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
-
include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 5c55efb8..ea444a4 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
package android.net;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
import android.net.RouteInfo;
@@ -26,6 +28,7 @@
import java.net.InetAddress;
import java.util.ArrayList;
+
public class LinkPropertiesTest extends TestCase {
private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1");
private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress(
@@ -567,4 +570,80 @@
assertEquals(ProvisioningChange.STILL_PROVISIONED,
LinkProperties.compareProvisioning(v6lp, v6lp2));
}
+
+ @SmallTest
+ public void testIsReachable() {
+ final LinkProperties v4lp = new LinkProperties();
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Add an on-link route, making the on-link DNS server reachable,
+ // but there is still no IPv4 address.
+ assertTrue(v4lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+ assertFalse(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding an IPv4 address (right now, any IPv4 address) means we use
+ // the routes to compute likely reachability.
+ assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertFalse(v4lp.isReachable(DNS2));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
+ assertTrue(v4lp.isReachable(DNS1));
+ assertTrue(v4lp.isReachable(DNS2));
+
+ final LinkProperties v6lp = new LinkProperties();
+ final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1");
+ final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43");
+ final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53");
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local route, making the link-local DNS servers reachable. Because
+ // we assume the presence of an IPv6 link-local address, link-local DNS servers
+ // are considered reachable, but only those with a non-zero scope identifier.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a link-local address--nothing changes.
+ assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertFalse(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global route on link, but no global address yet. DNS servers reachable
+ // via a route that doesn't require a gateway: give them the benefit of the
+ // doubt and hope the link-local source address suffices for communication.
+ assertTrue(v6lp.addRoute(new RouteInfo(
+ new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64))));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Add a global address; the on-link global address DNS server is (still)
+ // presumed reachable.
+ assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertFalse(v6lp.isReachable(DNS6));
+
+ // Adding a default route makes the off-link DNS server reachable.
+ assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
+ assertFalse(v6lp.isReachable(kLinkLocalDns));
+ assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
+ assertTrue(v6lp.isReachable(kOnLinkDns));
+ assertTrue(v6lp.isReachable(DNS6));
+ }
}
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
new file mode 100644
index 0000000..d2e2131
--- /dev/null
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.text.format;
+
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.format.Formatter.BytesResult;
+
+import java.util.Locale;
+
+public class FormatterTest extends AndroidTestCase {
+
+ private Locale mOriginalLocale;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mOriginalLocale = mContext.getResources().getConfiguration().locale;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mOriginalLocale != null) {
+ setLocale(mOriginalLocale);
+ }
+ super.tearDown();
+ }
+
+ private void setLocale(Locale locale) {
+ Resources res = getContext().getResources();
+ Configuration config = res.getConfiguration();
+ config.locale = locale;
+ res.updateConfiguration(config, res.getDisplayMetrics());
+
+ Locale.setDefault(locale);
+ }
+
+ @SmallTest
+ public void testFormatBytes() {
+ setLocale(Locale.ENGLISH);
+
+ checkFormatBytes(0, true, "0.00", 0);
+ checkFormatBytes(0, false, "0.00", 0);
+
+ checkFormatBytes(1, true, "1.0", 1);
+ checkFormatBytes(1, false, "1.00", 1);
+
+ checkFormatBytes(12, true, "12", 12);
+ checkFormatBytes(12, false, "12.00", 12);
+
+ checkFormatBytes(123, true, "123", 123);
+ checkFormatBytes(123, false, "123", 123);
+
+ checkFormatBytes(812, true, "812", 812);
+ checkFormatBytes(812, false, "812", 812);
+
+ checkFormatBytes(912, true, "0.89", 911);
+ checkFormatBytes(912, false, "0.89", 911);
+
+ checkFormatBytes(9123, true, "8.9", 9113);
+ checkFormatBytes(9123, false, "8.91", 9123);
+
+ checkFormatBytes(9123000, true, "8.7", 9122611);
+ checkFormatBytes(9123000, false, "8.70", 9122611);
+
+ // The method doesn't really support negative values, but apparently people pass -1...
+ checkFormatBytes(-1, true, "-1.00", -1);
+ checkFormatBytes(-1, false, "-1.00", -1);
+
+ // Missing FLAG_CALCULATE_ROUNDED case.
+ BytesResult r = Formatter.formatBytes(getContext().getResources(), 1, 0);
+ assertEquals("1.00", r.value);
+ assertEquals(0, r.roundedBytes); // Didn't pass FLAG_CALCULATE_ROUNDED
+
+ // Make sure it works on different locales.
+ setLocale(new Locale("es", "ES"));
+ checkFormatBytes(9123000, false, "8,70", 9122611);
+ }
+
+ private void checkFormatBytes(long bytes, boolean useShort,
+ String expectedString, long expectedRounded) {
+ BytesResult r = Formatter.formatBytes(getContext().getResources(), bytes,
+ Formatter.FLAG_CALCULATE_ROUNDED | (useShort ? Formatter.FLAG_SHORTER : 0));
+ assertEquals(expectedString, r.value);
+ assertEquals(expectedRounded, r.roundedBytes);
+ }
+}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index a50fb54..31a4703 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -51,11 +51,15 @@
private static final Locale LOCALE_FR = new Locale("fr");
private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
private static final Locale LOCALE_HI = new Locale("hi");
+ private static final Locale LOCALE_JA = new Locale("ja");
private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
private static final Locale LOCALE_IN = new Locale("in");
private static final Locale LOCALE_ID = new Locale("id");
+ private static final Locale LOCALE_TH = new Locale("ht");
+ private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
+ private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
private static final String SUBTYPE_MODE_ANY = null;
@@ -849,4 +853,99 @@
return preinstalledImes;
}
+
+ @SmallTest
+ public void testGetSuitableLocalesForSpellChecker() throws Exception {
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_US, locales.get(0));
+ assertEquals(LOCALE_EN_GB, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_GB, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
+ assertEquals(4, locales.size());
+ assertEquals(LOCALE_EN_IN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ assertEquals(LOCALE_EN, locales.get(3));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test 3-letter language code.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_FIL_PH, locales.get(0));
+ assertEquals(LOCALE_FIL, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test variant.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
+ assertEquals(6, locales.size());
+ assertEquals(LOCALE_TH_TH_TH, locales.get(0));
+ assertEquals(LOCALE_TH_TH, locales.get(1));
+ assertEquals(LOCALE_TH, locales.get(2));
+ assertEquals(LOCALE_EN_US, locales.get(3));
+ assertEquals(LOCALE_EN_GB, locales.get(4));
+ assertEquals(Locale.ENGLISH, locales.get(5));
+ }
+
+ // Test Locale extension.
+ {
+ final Locale localeWithoutVariant = LOCALE_JA_JP;
+ final Locale localeWithVariant = new Locale.Builder()
+ .setLocale(LOCALE_JA_JP)
+ .setExtension('x', "android")
+ .build();
+ assertFalse(localeWithoutVariant.equals(localeWithVariant));
+
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+ }
}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index c517201..377e6a16 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -58,21 +58,6 @@
<group gid="log" />
</permission>
- <permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
- <group gid="sdcard_r" />
- </permission>
-
- <permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
- <group gid="sdcard_r" />
- <group gid="sdcard_rw" />
- </permission>
-
- <permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
- <group gid="sdcard_r" />
- <group gid="sdcard_rw" />
- <group gid="sdcard_all" />
- </permission>
-
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
<group gid="media_rw" />
</permission>
diff --git a/docs/html-intl/intl/es/preview/api-overview.jd b/docs/html-intl/intl/es/preview/api-overview.jd
new file mode 100644
index 0000000..ddd34db
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=Información general de la API
+page.keywords=versión preliminar,sdk,compatibilidad
+page.tags=recursos de la versión preliminar, androidm
+sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Contenido del documento<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+
+ <span class="more">mostrar más</span>
+ <span class="less" style="display:none">mostrar menos</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">Vinculación de la aplicación</a></li>
+ <li><a href="#backup">Copia de seguridad automática para aplicaciones</a></li>
+ <li><a href="#authentication">Autenticación</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">Autenticación por huellas dactilares</a></li>
+ <li><a href="#confirm-credential">Confirmar credencial</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">Compartir de forma directa</a></li>
+ <li><a href="#voice-interactions">Interacciones de voz</a></li>
+ <li><a href="#assist">Asistencia de API</a></li>
+ <li><a href="#notifications">Notificaciones</a></li>
+ <li><a href="#bluetooth-stylus">Soporte del lápiz Bluetooth</a></li>
+ <li><a href="#ble-scanning">Exploración mejorada de Bluetooth de bajo consumo</a></li>
+ <li><a href="#hotspot">Soporte de Hotspot 2.0 versión 1</a></li>
+ <li><a href="#4K-display">Modo de pantalla 4K</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">ColorStateLists para poder aplicar temas</a></li>
+ <li><a href="#audio">Características de audio</a></li>
+ <li><a href="#video">Características de video</a></li>
+ <li><a href="#camera">Características de la cámara</a>
+ <ol>
+ <li><a href="#flashlight">API para luz de flash</a></li>
+ <li><a href="#reprocessing">Reprocesamiento de la cámara</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Características de Android for Work</a></li>
+</ol>
+
+<h2>Diferencias de las API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">Nivel de API 22 para la versión preliminar de Android M »</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview le brinda una perspectiva avanzada de la próxima versión de la plataforma Android, que ofrece nuevas características para usuarios y desarrolladores de aplicaciones.
+
+ En este documento, se brinda una introducción sobre las API más distinguidas.</p>
+
+<p>M Developer Preview está destinado a <strong>usuarios desarrolladores principiantes</strong> y <strong>evaluadores</strong>.
+ Si le interesa influenciar la dirección del marco de trabajo de Android,
+<a href="{@docRoot}preview/setup-sdk.html">pruebe M Developer Preview y</a> envíenos sus comentarios.
+
+</p>
+
+<p class="caution"><strong>Advertencia:</strong> No publique las aplicaciones que utilizan M Developer Preview en la tienda de Google Play.
+</p>
+
+<p class="note"><strong>Nota:</strong> Este documento, a menudo, hace referencia a clases y métodos que aún no cuentan con materiales de referencia disponibles en <a href="{@docRoot}">developer.android.com</a>.
+ Estos elementos de API tienen el formato {@code code style} en este documento (sin hipervínculos).
+ Para obtener la documentación preliminar de la API para estos elementos, descargue la <a href="{@docRoot}preview/download.html#docs"> referencia de la versión preliminar</a>.
+</p>
+
+<h3>Importantes cambios en los comportamientos</h3>
+
+<p>Si publicó anteriormente una aplicación para Android, tenga en cuenta que su aplicación podría verse afectada por los cambios en la plataforma.
+</p>
+
+<p>Consulte la sección <a href="behavior-changes.html">Cambios en los comportamientos</a> para obtener información detallada.</p>
+
+<h2 id="app-linking">Vinculación de la aplicación</h2>
+<p>Esta versión preliminar mejora el sistema de intentos de Android al proporcionar una vinculación más sólida de la aplicación. Esta característica le permite asociar una aplicación con un dominio web propio.
+ Según esta asociación, la plataforma puede determinar la aplicación predeterminada que se debe utilizar para controlar un vínculo web en particular y omitir el paso de pedirles a los usuarios que seleccionen una aplicación. Para aprender a implementar esta característica, consulte la sección
+<a href="{@docRoot}preview/features/app-linking.html">Vinculación de la aplicación</a>.
+
+
+
+<h2 id="backup">Copia de seguridad automática para aplicaciones</h2>
+<p>Ahora, el sistema realiza restauraciones y copias de seguridad de datos completas y automáticas para las aplicaciones. Este comportamiento se habilita de forma predeterminada para las aplicaciones que tienen como destino la versión preliminar de Android M; usted no necesita agregar ningún código adicional.
+ Si los usuarios eliminan sus cuentas de Google, también se eliminarán sus datos de copias de seguridad.
+ Para obtener información sobre cómo funciona esta característica y cómo configurar qué elementos incluir en la copia de seguridad del sistema de archivo, consulte la sección
+<a href="{@docRoot}preview/backup/index.html">Copia de seguridad automática para aplicaciones</a>.
+</p>
+
+<h2 id="authentication">Autenticación</h2>
+<p>Esta versión preliminar ofrece nuevas API para permitirle autenticar usuarios al usar escaneos de huellas dactilares en los dispositivos compatibles y verificar cuán reciente es la última autenticación del usuario al utilizar un mecanismo de desbloqueo de dispositivos (como una contraseña de pantalla de bloqueo).
+
+ Use estas API junto con el <a href="{@docRoot}training/articles/keystore.html">sistema Android Keystore</a>.
+</p>
+
+<h3 id="fingerprint-authentication">Autenticación por huellas dactilares</h3>
+
+<p>Para autenticar usuarios mediante el escaneo de huellas dactilares, obtenga una instancia de la nueva clase
+{@code android.hardware.fingerprint.FingerprintManager} y llame al método
+{@code FingerprintManager.authenticate()}. Su aplicación se debe ejecutar en un dispositivo compatible con un sensor de huellas dactilares.
+ Debe implementar la interfaz de usuario para el flujo de autenticación por huellas dactilares en su aplicación y debe utilizar el ícono de huella dactilar estándar de Android en la UI. El ícono de huella dactilar de Android ({@code c_fp_40px.png}) se incluye en la
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">aplicación de muestra</a>. Si está desarrollando múltiples aplicaciones que utilizan la autenticación por huellas dactilares, tenga en cuenta que cada aplicación debe autenticar la huella dactilar del usuario de manera independiente.
+
+
+
+</p>
+
+<p>Para utilizar esta característica en su aplicación, primero agregue el permiso {@code USE_FINGERPRINT} en su manifiesto.
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>Para ver cómo una aplicación implementa la autenticación por huellas dactilares, consulte la sección
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
+Ejemplo de diálogo de huella dactilar</a>.</p>
+
+<p>Si está evaluando esta característica, siga estos pasos:</p>
+<ol>
+<li>Instale la Revisión de herramientas del SDK de Android versión 24.3, si todavía no la instaló.</li>
+<li>Registre una huella dactilar nueva en el emulador; para hacerlo, vaya a
+<strong>Settings > Security > Fingerprint</strong>, luego siga las instrucciones de registro.</li>
+<li>Use un emulador para emular eventos táctiles de huellas dactilares con el siguiente comando.
+ Utilice el mismo comando para emular eventos táctiles de huellas dactilares en la pantalla de bloqueo o en su aplicación.
+
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>En Windows, posiblemente tenga que ejecutar {@code telnet 127.0.0.1 <emulator-id>} seguido de
+ {@code finger touch <finger_id>}.
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">Confirmar credencial</h3>
+<p>Su aplicación puede autenticar usuarios según el tiempo que haya pasado desde que desbloquearon su dispositivo por última vez. Esta característica evita que los usuarios tengan que recordar contraseñas adicionales específicas de la aplicación y elimina la necesidad de que usted tenga que implementar su propia interfaz de usuario de autenticación.
+
+ Su aplicación debe utilizar esta característica junto con una implementación de clave pública o secreta para la autenticación del usuario.
+</p>
+
+<p>Para definir la duración del tiempo de espera en el que se puede volver a usar la misma clave después de que un usuario se haya autenticado correctamente, llame al nuevo método
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+cuando configure {@link javax.crypto.KeyGenerator} o
+{@link java.security.KeyPairGenerator}.
+ Esta característica actualmente funciona para operaciones criptográficas simétricas.
+</p>
+
+<p>Evite mostrar el diálogo de nueva autenticación de forma excesiva: sus aplicaciones deben intentar utilizar el objeto criptográfico primero y, si se agota el tiempo de espera, deben usar el método
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+para volver a autenticar el usuario dentro de su aplicación.
+
+</p>
+
+<p>Para ver cómo la aplicación implementa esta característica, consulte la sección
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">
+Ejemplo de cómo confirmar la credencial</a>.</p>
+
+<h2 id="direct-share">Compartir de forma directa</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>Esta versión preliminar le proporciona API para que la acción de compartir sea intuitiva y rápida para los usuarios. Ahora, puede definir <em>destinos para compartir de forma directa</em> que inician una actividad específica en su aplicación. Estos destinos para compartir de forma directa se exponen a los usuarios a través del menú <em>Share</em>.
+
+ Esta característica les permite a los usuarios compartir contenido con los destinos, como contactos, dentro de otras aplicaciones.
+ Por ejemplo, el destino para compartir de forma directa podría iniciar una actividad en otra aplicación de red social, lo que le permite al usuario compartir contenido directamente con una comunidad o un amigo específicos de esa aplicación.
+
+</p>
+
+<p>Para habilitar destinos para compartir de forma directa, debe definir una clase que extienda el
+{@code android.service.} <br>
+Clase {@code chooser.ChooserTargetService}. Declare su
+{@code ChooserTargetService} en el manifiesto. En esa declaración, especifique el permiso
+{@code BIND_CHOOSER_TARGET_SERVICE} y un filtro de intento con la acción
+{@code SERVICE_INTERFACE}.</p>
+<p>El ejemplo a continuación muestra de qué manera podría declarar {@code ChooserTargetService} en su manifiesto.
+</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>Para cada actividad que desee exponer a {@code ChooserTargetService}, agregue un elemento
+{@code <meta-data>} con el nombre
+{@code "android.service.chooser.chooser_target_service"} en el manifiesto de su aplicación.
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">Interacciones de voz</h2>
+<p>
+Esta versión preliminar proporciona una nueva API de interacción de voz que, junto con las
+<a href="https://developers.google.com/voice-actions/" class="external-link">acciones de voz</a>,
+le permite compilar experiencias de conversaciones de voz en sus aplicaciones. Llame al método
+{@code android.app.Activity.isVoiceInteraction()} para determinar si su actividad se inició en respuesta a una acción de voz.
+ De ser así, su aplicación puede utilizar la clase
+{@code android.app.VoiceInteractor} para solicitar una confirmación de voz por parte del usuario, realizar una selección de una lista de opciones y mucho más.
+ Para obtener más información sobre cómo implementar acciones de voz, consulte el
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">sitio para desarrolladores de acciones de voz</a>.
+</p>
+
+<h2 id="assist">Asistencia de API</h2>
+<p>
+Esta versión preliminar ofrece una nueva manera para que los usuarios interactúen con sus aplicaciones a través de un asistente. Si desea utilizar esta característica, el usuario debe habilitar el asistente para utilizar el contexto actual.
+ Una vez habilitado, para invocar al asistente dentro de cualquier aplicación, el usuario debe mantener presionado el botón <strong>Home</strong>.
+</p>
+<p>Su aplicación puede optar por no compartir el contexto actual con el asistente al configurar la marca
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE}. Además del conjunto de información estándar que la plataforma le pasa al asistente, su aplicación puede compartir información adicional usando la nueva clase {@code android.app.Activity.AssistContent}.
+
+</p>
+
+<p>Para proporcionarle al asistente contexto adicional desde su aplicación, siga estos pasos:</p>
+
+<ol>
+<li>Implemente la interfaz {@link android.app.Application.OnProvideAssistDataListener}.</li>
+<li>Registre esta escucha usando
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
+<li>Para proporcionar información contextual específica de la actividad, invalide la devolución de llamada
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+y, opcionalmente, la nueva devolución de llamada {@code Activity.onProvideAssistContent()}.
+</ol>
+
+<h2 id="notifications">Notificaciones</h2>
+<p>Esta versión preliminar agrega los siguientes cambios de API para las notificaciones:</p>
+<ul>
+ <li>Nuevo nivel de filtro {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} que corresponde al nuevo modo ocupado <em>Solo alarmas</em>.
+</li>
+ <li>Nuevo valor de categoría {@code Notification.CATEGORY_REMINDER} que se utiliza para distinguir recordatorios programados por el usuario de otros eventos
+ ({@link android.app.Notification#CATEGORY_EVENT}) y alarmas
+ ({@link android.app.Notification#CATEGORY_ALARM}).
+</li>
+ <li>Nueva clase {@code android.graphics.drawable.Icon} que se puede adjuntar a sus notificaciones a través de los métodos {@code Notification.Builder.setSmallIcon(Icon)} y
+{@code Notification.Builder.setLargeIcon(Icon)}.
+</li>
+ <li>Nuevo método {@code NotificationManager.getActiveNotifications()} que permite que sus aplicaciones descubran qué notificaciones se encuentran actualmente activas.
+ Para ver una implementación de la aplicación que utilice esta característica, consulte la sección <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">Ejemplo de notificaciones activas</a>.
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Compatibilidad del lápiz Bluetooth</h2>
+<p>Esta versión preliminar ofrece soporte mejorado para las entradas de usuarios que utilizan un lápiz Bluetooth. Los usuarios pueden sincronizar y conectar un lápiz Bluetooth compatible con su teléfono o tablet.
+ Mientras está conectado, la información de posición de la pantalla táctil se fusiona con la información de los botones y la presión del lápiz para proporcionar una mayor variedad de expresiones que al utilizar la pantalla táctil solamente.
+
+ Su aplicación puede obedecer cuando se presiona el botón del lápiz y cuando se realizan acciones secundarias al registrar las nuevas devoluciones de llamadas
+{@code View.onStylusButtonPressListener} y {@code GestureDetector.OnStylusButtonPressListener}
+en su actividad.
+</p>
+
+<p>Utilice las constantes y los métodos {@link android.view.MotionEvent} para detectar las interacciones del botón del lápiz:
+</p>
+<ul>
+<li>Si el usuario toca un lápiz con un botón en la pantalla de su aplicación, el método
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} devuelve
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
+<li>Para las aplicaciones que tienen como destino la versión preliminar de Android M, el método
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+devuelve {@code MotionEvent.STYLUS_BUTTON_PRIMARY} cuando el usuario presiona el botón principal del lápiz.
+ Si el lápiz tiene un segundo botón, el mismo método devuelve
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY} cuando el usuario lo presiona. Si el usuario presiona ambos botones simultáneamente, el método devuelve ambos valores juntos separados por “OR” ({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).
+
+</li>
+<li>
+Para las aplicaciones que tienen como destino una versión anterior de la plataforma, el método
+{@link android.view.MotionEvent#getButtonState() getButtonState()} devuelve
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (cuando se presiona el botón principal),
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (cuando se presiona el botón secundario) o ambos.
+</li>
+</ul>
+
+<h2 id="ble-scanning">Exploración mejorada de Bluetooth de bajo consumo</h2>
+<p>
+Si su aplicación realiza exploraciones de Bluetooth de bajo consumo, puede utilizar el nuevo método
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} para especificar que usted desea que las devoluciones de llamadas se notifiquen solo cuando se encuentre por primera vez un paquete de anuncio que coincida con el conjunto
+{@link android.bluetooth.le.ScanFilter} y cuando no se vea durante un período determinado.
+
+ Este enfoque de exploración es más eficaz en cuanto al consumo de energía que la que se proporciona en la versión anterior de la plataforma.
+
+</p>
+
+<h2 id="hotspot">Soporte de Hotspot 2.0 versión 1</h2>
+<p>
+Esta versión preliminar agrega soporte para la especificación de Hotspot 2.0 versión 1 en los dispositivos Nexus 6 y Nexus 9. Para proveer credenciales de Hotspot 2.0 en su aplicación, use los métodos nuevos de la clase
+{@link android.net.wifi.WifiEnterpriseConfig}, como {@code setPlmn()} y
+{@code setRealm()}.
+ En el objeto {@link android.net.wifi.WifiConfiguration}, puede configurar los campos
+{@link android.net.wifi.WifiConfiguration#FQDN} y {@code providerFriendlyName}. La nueva propiedad {@code ScanResult.PasspointNetwork} indica si una red detectada representa un punto de acceso de Hotspot 2.0.
+
+
+</p>
+
+<h2 id="4K-display">Modo de pantalla 4K</h2>
+<p>Ahora, la plataforma permite que las aplicaciones soliciten que la resolución de pantalla se actualice a una representación 4K en el hardware compatible.
+ Para consultar la resolución física actual, use las nuevas API
+{@code android.view.Display.Mode}. Si la UI se establece en una resolución lógica más baja y se aumenta a una resolución física más alta, tenga en cuenta que la resolución física que devuelve el método
+{@code Display.Mode.getPhysicalWidth()} puede ser diferente de la resolución lógica informada por {@link android.view.Display#getSize(android.graphics.Point) getSize()}.
+
+</p>
+
+<p>Puede pedirle al sistema que cambie la resolución física en su aplicación mientras se ejecuta y, para ello, debe configurar la propiedad {@code WindowManager.LayoutParams.preferredDisplayModeId} de la ventana de su aplicación.
+ Esta característica resulta útil si desea cambiar a la resolución de pantalla 4K.
+ Mientras se encuentra en el modo de pantalla 4K, la UI se continúa representando en la resolución original (como 1080p) y se aumenta a 4K, pero los objetos
+{@link android.view.SurfaceView} pueden mostrar contenido en la resolución nativa.
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">ColorStateLists para poder aplicar temas</h2>
+<p>Ahora, los atributos de tema se admiten en
+{@link android.content.res.ColorStateList} para los dispositivos que ejecutan la versión preliminar de Android M. Los métodos
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} y
+{@link android.content.res.Resources#getColor(int) getColor()} se dejaron de usar. Si desea llamar a estas API, en su lugar, llame a los métodos nuevos {@code Context.getColorStateList()} o
+{@code Context.getColor()}.
+ Estos métodos también se encuentran disponibles en la biblioteca AppCompat v4 vía {@link android.support.v4.content.ContextCompat}.
+</p>
+
+<h2 id="audio">Características de audio</h2>
+
+<p>Esta versión preliminar agrega mejoras al procesamiento de audio en Android, lo que incluye lo siguiente: </p>
+<ul>
+ <li>Soporte para el protocolo <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+, con las nuevas API {@code android.media.midi}. Utilice estas API para enviar y recibir eventos MIDI.
+</li>
+ <li>Clases nuevas {@code android.media.AudioRecord.Builder} y {@code android.media.AudioTrack.Builder}
+ para crear capturas de audio digital y objetos de reproducción respectivamente, y configurar propiedades de receptores y fuentes de audio para invalidar los valores predeterminados del sistema.
+</li>
+ <li>Enlaces de API para asociar dispositivos de entrada y de audio. Esto resulta particularmente útil si su aplicación les permite a los usuarios iniciar una búsqueda por voz desde un controlador para juegos o un control remoto conectados a un TV con Android. El sistema invoca la nueva devolución de llamada {@code android.app.Activity.onSearchRequested()} cuando el usuario inicia una búsqueda.
+
+
+ Para determinar si el dispositivo de entrada del usuario tiene un micrófono incorporado, recupere el objeto {@link android.view.InputDevice} de esa devolución de llamada y luego llame al nuevo método
+{@code InputDevice.hasMic()}.
+</li>
+ <li>Nueva clase {@code android.media.AudioDevicesManager}, que le permite recuperar una lista de todos los dispositivos de audio receptores y fuente adjuntos.
+ También puede especificar un objeto
+{@code android.media.OnAudioDeviceConnectionListener} si desea que su aplicación reciba una notificación cuando se conecta o desconecta un dispositivo de audio.
+</li>
+</ul>
+
+<h2 id="video">Características de video</h2>
+<p>Esta versión preliminar agrega nuevas capacidades a las API de procesamiento de video, entre ellas, las siguientes:</p>
+<ul>
+<li>Nueva clase {@code android.media.MediaSync} que ayuda a las aplicaciones a representar de forma sincrónica transmisiones de audio y video.
+ Los búferes de audio se envían de manera que no generan bloqueo y regresan mediante una devolución de llamada.
+ Además, admite una velocidad de reproducción dinámica.
+</li>
+<li>Nuevo evento {@code MediaDrm.EVENT_SESSION_RECLAIMED}, que indica cuando una sesión abierta por la aplicación es reclamada por el administrador de recursos.
+ Si su aplicación utiliza sesiones DRM, debe controlar este evento y asegurarse de no utilizar una sesión reclamada.
+
+</li>
+<li>Nuevo código de error {@code MediaCodec.CodecException.ERROR_RECLAIMED}, que indica que el administrador de recursos reclamó el recurso multimedia utilizado por el códec.
+ Con esta excepción, se debe liberar el códec, ya que pasó al estado terminal.
+
+</li>
+<li>Nueva interfaz {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} para obtener una indicación de la cantidad máxima de instancias concurrentes de códec admitidas.
+
+</li>
+<li>Nuevo método {@code MediaPlayer.setPlaybackParams()} para configurar la velocidad de reproducción multimedia para reproducciones rápidas o lentas.
+ Además, alarga o acelera la reproducción de audio de forma automática junto con el video.
+</li>
+</ul>
+
+<h2 id="camera">Características de la cámara</h2>
+<p>Esta versión preliminar incluye las siguientes API nuevas para acceder a la luz de flash de la cámara y para el reprocesamiento de imágenes de la cámara:
+</p>
+
+<h3 id="flashlight">API para luz de flash</h3>
+<p>Si un dispositivo de cámara cuenta con una unidad de flash, puede llamar al método {@code CameraManager.setTorchMode()}
+para activar o desactivar el modo linterna de una unidad de flash sin abrir el dispositivo de cámara. La aplicación no tiene propiedad exclusiva de la unidad de flash ni del dispositivo de cámara.
+ El modo linterna se desactiva y deja de estar disponible cuando la cámara no se encuentra disponible o cuando otros recursos de la cámara que mantienen la linterna encendida dejan de estar disponibles.
+
+ Otras aplicaciones también pueden llamar a {@code setTorchMode()}
+para desactivar el modo linterna. Cuando se cierra la última aplicación que activó el modo linterna, este modo se desactiva.
+</p>
+
+<p>Si desea registrar una devolución de llamada para recibir una notificación sobre el estado del modo linterna, llame al método
+{@code CameraManager.registerTorchCallback()}. La primera vez que se registra la devolución de llamada, se llama inmediatamente con el estado del modo linterna de todos los dispositivos de cámara que se conocen actualmente y que tengan una unidad de flash.
+
+ Si el modo linterna se activa o desactiva correctamente, se invoca al método
+{@code CameraManager.TorchCallback.onTorchModeChanged()}.</p>
+
+<h3 id="reprocessing">API de reprocesamiento</h3>
+<p>La API {@link android.hardware.camera2 Camera2} se extiende para admitir el reprocesamiento de imágenes privadas de formato opaco y YUV.
+ Su aplicación determina si las capacidades de reprocesamiento se encuentran disponibles vía {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}.
+ Si un dispositivo admite el reprocesamiento, usted puede crear una sesión de captura de cámara reprocesable llamando a
+{@code CameraDevice.createReprocessableCaptureSession()} y puede crear solicitudes para el reprocesamiento de búferes de entrada.
+
+</p>
+
+<p>Utilice la clase {@code ImageWriter} para conectar el flujo del búfer de entrada a la entrada de reprocesamiento de la cámara.
+ Para obtener un búfer vacío, siga el modelo de programación que se indica a continuación:</p>
+
+<ol>
+<li>Llame al método {@code ImageWriter.dequeueInputImage()}.</li>
+<li>Complete los datos en el búfer de entrada.</li>
+<li>Envíe el búfer a la cámara llamando al método {@code ImageWriter.queueInputImage()}.</li>
+</ol>
+
+<p>Si está utilizando un objeto {@code ImageWriter} junto con una imagen
+{@code android.graphics.ImageFormat.PRIVATE}, su aplicación no puede acceder a los datos de la imagen de forma directa.
+ En cambio, pase la imagen {@code ImageFormat.PRIVATE} directamente a
+{@code ImageWriter} llamando al método {@code ImageWriter.queueInputImage()} sin ninguna copia del búfer.
+</p>
+
+<p>La clase {@code ImageReader} ahora admite secuencias de imagen de formato {@code android.graphics.ImageFormat.PRIVATE}.
+ Este soporte le permite que su aplicación mantenga una cola de imagen circular de imágenes de salida
+{@code ImageReader}, seleccione una o más imágenes y las envíe a
+{@code ImageWriter} para el reprocesamiento de la cámara.</p>
+
+<h2 id="afw">Características de Android for Work</h2>
+<p>Esta versión preliminar incluye las siguientes API nuevas para Android for Work:</p>
+<ul>
+ <li><strong>Controles mejorados para dispositivos corporativos de uso único:</strong> El propietario de dispositivo ahora puede controlar las configuraciones que se describen a continuación para mejorar la administración de los dispositivos corporativos de uso único (Corporate-Owned, Single-Use, COSU).
+
+
+ <ul>
+ <li>Deshabilitar o volver a habilitar la protección de seguridad con el método
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Deshabilitar o volver a habilitar la barra de estado (lo que incluye configuraciones rápidas, notificaciones y el gesto de navegación al deslizar el dedo hacia arriba para iniciar Google Now) con el método
+{@code DevicePolicyManager.setStatusBarEnabledState()}.
+</li>
+ <li>Deshabilitar o volver a habilitar el inicio seguro con la constante {@link android.os.UserManager}
+{@code DISALLOW_SAFE_BOOT}.</li>
+ <li>Evitar que se apague la pantalla mientras el dispositivo se encuentra conectado con la constante
+ {@link android.provider.Settings.Global} {@code STAY_ON_WHILE_PLUGGED_IN}.</li>
+ </ul>
+ </li>
+ <li><strong>Instalación y desinstalación automáticas de aplicaciones por parte del propietario de dispositivo:</strong> Un propietario de dispositivo ahora puede instalar y desinstalar aplicaciones de manera automática con las API {@link android.content.pm.PackageInstaller}
+, independiente de Google Play for Work.
+ Ahora, puede aprovisionar los dispositivos a través de un propietario de dispositivo que obtiene e instala aplicaciones sin interacción del usuario.
+ Esta característica es útil para habilitar el aprovisionamiento con un toque de quioscos u otros dispositivos similares sin activar una cuenta de Google.
+</li>
+<li><strong>Acceso automático al certificado de empresa:</strong> Ahora cuando una aplicación llama a
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()}, antes de que se indique al usuario que seleccione un certificado, el propietario de dispositivo o perfil puede llamar al método {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} para proporcionar el alias de forma automática a la aplicación que realiza la solicitud.
+
+
+ Esta característica le permite conceder a las aplicaciones gestionadas acceso a certificados sin interacción del usuario.
+</li>
+<li><strong>Aceptación automática de actualizaciones del sistema:</strong> Al configurar una directiva de actualización del sistema con
+{@code DevicePolicyManager.setSystemUpdatePolicy()}, el propietario de dispositivo ahora puede aceptar automáticamente una actualización del sistema, por ejemplo, en el caso de un dispositivo de quiosco, o posponer la actualización y evitar que el usuario la ejecute durante un plazo de hasta 30 días.
+
+ Además, un administrador puede configurar un período de tiempo diario en el que se debe ejecutar una actualización, por ejemplo, durante las horas en que no se usa el dispositivo de quiosco.
+ Cuando hay una actualización del sistema disponible, el sistema verifica si la aplicación Work Policy Controller definió una directiva de actualización del sistema y se comporta según corresponda.
+
+
+</li>
+<li>
+<strong>Instalación delegada de certificados:</strong> Ahora, un propietario de dispositivo o perfil puede concederle a una aplicación de terceros la capacidad de llamar a estas API de administración de certificados {@link android.app.admin.DevicePolicyManager}:
+
+
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>Protección de restablecimiento de la configuración predeterminada de fábrica:</strong> Al aprovisionar a un propietario de dispositivo, ahora podrá configurar parámetros para desbloquear la protección de restablecimiento de la configuración predeterminada de fábrica (Factory Reset Protection, FRP) configurando el paquete
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}.
+ Una aplicación de Programador NFC puede proporcionar estos parámetros después del restablecimiento de un dispositivo para desbloquear la FRP y aprovisionar al dispositivo sin requerir la cuenta de Google configurada previamente.
+
+ Si no modifica estos parámetros, la FRP se conserva y evita que el dispositivo se active sin las credenciales de Google activadas previamente.
+
+
+<p>Además, al configurar las restricciones de la aplicación en los servicios de Google Play, los propietarios de dispositivos pueden especificar cuentas de Google alternativas para desbloquear la FRP y reemplazar las que se encuentran activadas en el dispositivo.
+</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>Seguimiento del uso de datos:</strong> Ahora, un propietario de dispositivo o perfil puede consultar las estadísticas de uso de datos que se pueden ver en <strong>Settings > Data</strong> utilizando los nuevos métodos
+{@code android.app.usage.NetworkStatsManager}.
+ A los propietarios de perfiles se les concede automáticamente permiso para consultar los datos del perfil que administran, mientras que los propietarios de dispositivo obtienen acceso a los datos de uso del usuario principal administrado.
+
+</li>
+<li><strong>Administración de permisos de tiempo de ejecución:</strong>
+<p>Un propietario de dispositivo o perfil puede configurar una directiva de permisos para todas las solicitudes de tiempo de ejecución de todas las aplicaciones que utilizan
+{@code DevicePolicyManager.setPermissionPolicy()}, a fin de pedirle confirmación al usuario para conceder el permiso de manera normal, o bien, para conceder o negar el permiso automáticamente sin notificarlo.
+
+ Si se configura la última directiva, el usuario no puede modificar la selección realizada por el propietario de dispositivo o perfil dentro de la pantalla de permisos de la aplicación en <strong>Settings</strong>.
+
+</p></li>
+<li><strong>VPN en Settings:</strong> Las aplicaciones de la VPN (red privada virtual) ahora se pueden ver en
+<strong>Settings > More > VPN</strong>. Además, las notificaciones que acompañan el uso de la VPN ahora son específicas para la manera en que dicha VPN está configurada.
+
+ Para el propietario de perfil, las notificaciones son específicas dependiendo de si la VPN se configura para un perfil administrado, un perfil personal o ambos.
+ Para un propietario de dispositivo, las notificaciones son específicas dependiendo de si la VPN se configura para todo el dispositivo.
+</li>
+<li><strong>Notificación del estado del trabajo:</strong> Ahora aparecerá un ícono de maletín en la barra de estado siempre que una aplicación del perfil administrado tenga una actividad en primer plano.
+ Además, si el dispositivo se desbloquea directamente para la actividad de una aplicación del perfil administrado, se mostrará una notificación del sistema para informarle al usuario que se encuentra dentro del perfil de trabajo.
+
+
+</li>
+</ul>
+
+<p class="note">
+ Para obtener una vista detallada de todos los cambios de la API en M Developer Preview, consulte el <a href="{@docRoot}preview/download.html">Informe de diferencias de las API</a>.
+</p>
diff --git a/docs/html-intl/intl/es/preview/behavior-changes.jd b/docs/html-intl/intl/es/preview/behavior-changes.jd
new file mode 100644
index 0000000..75936bd
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/behavior-changes.jd
@@ -0,0 +1,403 @@
+page.title=Cambios en los comportamientos
+page.keywords=versión preliminar,sdk,compatibilidad
+sdk.platform.apiLevel=MNC
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Contenido del documento</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">Permisos de tiempo de ejecución</a></li>
+ <li><a href="#behavior-power">Optimizaciones de ahorro de energía</a>
+ <ol>
+ <li><a href="#behavior-doze">Doze</a></li>
+ <li><a href="#behavior-app-standby">App Standby</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">Dispositivos de almacenamiento adoptables</a></li>
+ <li><a href="#behavior-apache-http-client">Eliminación del cliente HTTP de Apache</a></li>
+ <li><a href="#behavior-audiomanager-Changes">Cambios en AudioManager</a></li>
+ <li><a href="#behavior-test-selection">Selección de texto</a></li>
+ <li><a href="#behavior-keystore">Cambios en Android Keystore</a></li>
+ <li><a href="#behavior-network">Cambios en las funciones de red y Wi-Fi</a></li>
+ <li><a href="#behavior-camera">Cambios en el servicio de cámara</a></li>
+ <li><a href="#behavior-art-runtime">Tiempo de ejecución de ART</a></li>
+ <li><a href="#behavior-apk-validation">Validación de APK</a></li>
+ <li><a href="#behavior-afw">Cambios en Android for Work</a></li>
+</ol>
+
+<h2>Diferencias de las API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">Nivel de API 22 para la versión preliminar de Android M »</a> </li>
+</ol>
+
+
+<h2>Consulte también</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Información general de la API de M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Además de nuevas características y capacidades, M Developer Preview incluye diversos cambios en el sistema y cambios en los comportamientos de la API.
+ En este documento, se destacan algunos de los cambios principales que debe comprender y justificar en sus aplicaciones.
+</p>
+
+<p>Si publicó anteriormente una aplicación para Android, tenga en cuenta que su aplicación podría verse afectada por estos cambios en la plataforma.
+</p>
+
+<h2 id="behavior-runtime-permissions">Permisos de tiempo de ejecución</h1>
+<p>Esta versión preliminar introduce un nuevo modelo de permisos en el que los usuarios ahora pueden administrar directamente los permisos de la aplicación en tiempo de ejecución.
+ Este modelo les proporciona a los usuarios mayor visibilidad y control sobre los permisos y, al mismo tiempo, simplifica los procesos de instalación y actualización automática para los desarrolladores de aplicaciones. Los usuarios pueden conceder o revocar permisos de forma individual para las aplicaciones instaladas.
+
+ </p>
+
+<p>En sus aplicaciones que tienen como destino la versión preliminar de Android M, asegúrese de comprobar y solicitar los permisos en tiempo de ejecución.
+ Para determinar si se concedió un permiso a su aplicación, llame al nuevo método {@code Context.checkSelfPermission()}.
+ Para solicitar un permiso, llame al nuevo método
+{@code Activity.requestPermission()}. Incluso si su aplicación no tiene como destino la versión preliminar de Android M, debería probar su aplicación de acuerdo con el nuevo modelo de permisos.
+</p>
+
+<p>Para obtener detalles sobre la compatibilidad del nuevo modelo de permisos en su aplicación, consulte la página
+<a href="{@docRoot}preview/features/runtime-permissions.html">
+Permisos</a> de la versión preliminar para desarrolladores. Para obtener consejos sobre cómo evaluar el impacto en su aplicación, consulte la <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Guía de prueba</a>.
+</p>
+
+<h2 id="behavior-power">Optimizaciones de ahorro de energía</h2>
+<p>Esta versión preliminar introduce nuevas optimizaciones de ahorro de energía para aplicaciones y dispositivos inactivos.</p>
+
+<h3 id="behavior-doze">Doze</h3>
+<p>Si un dispositivo está desconectado y permanece quieto con la pantalla apagada durante un período determinado, pasará al modo <em>Doze</em>, en el que el dispositivo intenta mantener el sistema en estado de suspensión.
+ En este modo, los dispositivos reanudan periódicamente el funcionamiento normal durante períodos breves, de manera que la aplicación se pueda sincronizar y el sistema pueda realizar las operaciones pendientes.
+
+</p>
+
+<p>Durante el modo Doze, se aplican las siguientes restricciones a sus aplicaciones:</p>
+<ul>
+<li>Se deshabilita el acceso a la red, salvo que su aplicación reciba una señal de prioridad alta de Google Cloud Messaging (envío de mensajes a través de la nube de Google).
+</li>
+<li>Se ignoran los <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wakelocks</a>.</li>
+<li>Se deshabilitan las alarmas programadas con la clase {@link android.app.AlarmManager}, salvo las alarmas que haya configurado con el método {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+y con {@code AlarmManager.setAndAllowWhileIdle()}.
+</li>
+<li>No se realiza la detección de Wi-Fi.</li>
+<li>No se permite la ejecución de sincronizaciones ni trabajos para sus adaptadores de sincronización y {@link android.app.job.JobScheduler}.
+</li>
+</ul>
+</p>
+<p>Al salir del modo Doze, el dispositivo ejecuta los trabajos y las sincronizaciones pendientes.</p>
+<p>Para probar esta característica, conecte un dispositivo que esté ejecutando la versión preliminar de Android M a su equipo de desarrollo y llame a los siguientes comandos:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>Nota:</strong> La próxima versión de
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> le permite designar mensajes de prioridad alta.
+ Si su aplicación recibe mensajes de GCM de prioridad alta, se le concede un breve acceso a la red, incluso cuando el dispositivo se encuentra en modo Doze.
+
+</p>
+
+<p>Consulte la
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Guía de prueba</a> para obtener consejos sobre cómo probar el modo Doze en su aplicación.
+ </p>
+
+<h3 id="behavior-app-standby">App Standby</h3>
+<p>Con esta versión preliminar, el sistema puede determinar que las aplicaciones se encuentran inactivas cuando no están en uso activo.
+ La aplicación se considera inactiva después de un cierto período, salvo que el sistema detecte alguna de las siguientes señales:
+</p>
+
+<ul>
+<li>El usuario inicia explícitamente la aplicación.</li>
+<li>La aplicación actualmente tiene un proceso en primer plano (ya sea como una actividad o un servicio en primer plano, o en uso por parte de otra actividad u otro servicio en primer plano).
+</li>
+<li>La aplicación genera una notificación que los usuarios ven en la pantalla de bloqueo o en la bandeja de notificaciones.
+</li>
+<li>El usuario solicita explícitamente que la aplicación esté exenta de optimizaciones mediante las <strong>Configuraciones</strong>.
+</li>
+</ul>
+
+<p>Si el dispositivo está desconectado, las aplicaciones que se consideren inactivas tendrán deshabilitado el acceso a la red y se suspenderán sus sincronizaciones y trabajos.
+ Cuando el dispositivo se conecte a un sistema de alimentación, estas aplicaciones se podrán conectar a la red y podrán ejecutar los trabajos y las sincronizaciones pendientes.
+ Si el dispositivo queda inactivo durante períodos prolongados, las aplicaciones inactivas pueden acceder a la red aproximadamente una vez al día.
+</p>
+
+<p>Para probar esta característica, conecte un dispositivo que esté ejecutando la versión preliminar de Android M a su equipo de desarrollo y llame a los siguientes comandos:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>Nota:</strong> La próxima versión de
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> (GCM) le permite designar mensajes de prioridad alta.
+ Si su aplicación recibe mensajes de GCM de prioridad alta, se le concede un breve acceso a la red, incluso cuando la aplicación está inactiva.
+
+</p>
+
+<p>Consulte la
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Guía de prueba</a> para obtener consejos sobre cómo probar el modo App Standby en sus aplicaciones.
+ </p>
+
+<h2 id="behavior-adoptable-storage">Dispositivos de almacenamiento adoptables</h2>
+<p>
+Con esta versión preliminar, los usuarios pueden <em>adoptar</em> dispositivos de almacenamiento externo, como tarjetas SD. Al adoptar un dispositivo de almacenamiento externo, el dispositivo se cifra y se formatea para que actúe como un elemento de almacenamiento interno.
+ Esta característica les permite a los usuarios mover tanto las aplicaciones como los datos privados de esas aplicaciones entre dispositivos de almacenamiento.
+ Al mover aplicaciones, el sistema respeta la preferencia
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+del manifiesto.
+</p>
+
+<p>Si su aplicación accede a las API o a los campos que se indican a continuación, tenga en cuenta que las rutas de archivo que devuelven se modificarán dinámicamente cuando la aplicación se mueva entre dispositivos de almacenamiento interno y externo. Al crear rutas de archivo, lo más recomendable es que siempre llame a estas API de forma dinámica. No use rutas de archivo codificadas de forma rígida ni continúe usando rutas de archivo completas que se hayan creado anteriormente.
+
+
+</p>
+
+<ul>
+<li>Métodos {@link android.content.Context}:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>Campos {@link android.content.pm.ApplicationInfo}:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>Para depurar esta característica en la versión preliminar para desarrolladores, puede habilitar la opción de adoptar una unidad USB que esté conectada a un dispositivo Android mediante un cable USB On-The-Go (OTG) y para habilitarla puede ejecutar el siguiente comando:
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Eliminación del cliente HTTP de Apache</h2>
+<p>Esta versión preliminar elimina el soporte del cliente HTTP de Apache. Si su aplicación utiliza este cliente y tiene como destino Android 2.3 (API de nivel 9) o una versión posterior, use, en su lugar, la clase {@link java.net.HttpURLConnection}.
+
+ Esta API es más eficaz porque reduce el uso de la red mediante compresión y almacenamiento de respuesta en caché transparentes, y minimiza el consumo de energía.
+ Para continuar utilizando las API HTTP de Apache, primero debe declarar la siguiente dependencia en tiempo de compilación en su archivo {@code build.gradle}:
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android está migrando de la biblioteca OpenSSL a
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Si utiliza Android NDK en su aplicación, no vincule bibliotecas criptográficas que no forman parte de la API de NDK, como {@code libcrypto.so} y {@code libssl.so}.
+ Estas bibliotecas no son API públicas y se pueden modificar o interrumpir sin aviso en todas las versiones y todos los dispositivos. Además, puede exponerse a vulnerabilidades de seguridad.
+
+ En cambio, modifique su código nativo para llamar a las API de criptografía de Java a través de JNI o para vincular estáticamente una biblioteca criptográfica de su elección.
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">Cambios en AudioManager</h2>
+<p>Ya no se admitirán las funciones de ajustar el volumen de forma directa o silenciar secuencias específicas por medio de la clase {@link android.media.AudioManager}
+. El método {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} es obsoleto, por lo que debe llamar al método
+{@code AudioManager.requestAudioFocus()} en su lugar. Del mismo modo, el método
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} es obsoleto; en su lugar, llame al método{@code AudioManager.adjustStreamVolume()} y pase los valores de dirección {@code ADJUST_MUTE} o {@code ADJUST_UNMUTE}.
+
+</p>
+
+<h2 id="behavior-test-selection">Selección de texto</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>Ahora, cuando los usuarios seleccionen texto en su aplicación, usted puede mostrar acciones de selección de texto, como
+<em>cortar</em>, <em>copiar</em> y <em>pegar</em> en una
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">barra de herramientas flotante</a>. La implementación de la interacción del usuario es similar a la de la barra de acciones contextuales, como se describe en la sección
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">
+Habilitación del modo de acción contextual para vistas individuales</a>.
+</p>
+
+<p>Si desea implementar una barra de herramientas flotante para selección de texto, realice los siguientes cambios en sus aplicaciones existentes:
+</p>
+<ol>
+<li>En su objeto {@link android.view.View} o {@link android.app.Activity}, cambie sus llamados
+{@link android.view.ActionMode} de
+{@code startActionMode(Callback)} a {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
+<li>Tome su implementación existente de {@code ActionMode.Callback} y, en su lugar, haga que sea extendida
+{@code ActionMode.Callback2}.</li>
+<li>Invalide el método {@code Callback2.onGetContentRect()} para proporcionar las coordenadas del objeto {@link android.graphics.Rect} de contenido (como un rectángulo de selección de texto) en la vista.
+</li>
+<li>Si el posicionamiento del rectángulo ya no es válido y este es el único elemento por invalidar, llame al método {@code ActionMode.invalidateContentRect()}.
+</li>
+</ol>
+
+<p>Si utiliza la biblioteca <a href="{@docRoot}tools/support-library/index.html">
+Android Support Library</a> versión 22.2, tenga en cuenta que las barras de herramientas flotantes no son compatibles con versiones anteriores y AppCompat toma el control de los objetos {@link android.view.ActionMode} de forma predeterminada.
+
+ Esto impide que se muestren las barras de herramientas flotantes. Para permitir la compatibilidad de
+{@link android.view.ActionMode} en
+{@link android.support.v7.app.AppCompatActivity}, llame a
+{@code android.support.v7.app.AppCompatActivity.getDelegate()}, luego llame a
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} en el objeto
+{@link android.support.v7.app.AppCompatDelegate} devuelto y configure el parámetro de entrada como {@code false}.
+ Esta llamada devuelve el control de los objetos {@link android.view.ActionMode} al marco de trabajo.
+ En los dispositivos que ejecutan la versión preliminar de Android M, eso permite que el marco de trabajo admita los modos de barras de herramientas flotantes o
+{@link android.support.v7.app.ActionBar}, mientras que en los dispositivos anteriores a la versión preliminar de Android M solo se admiten los modos {@link android.support.v7.app.ActionBar}.
+</p>
+
+<h2 id="behavior-keystore">Cambios en Android Keystore</h2>
+<p>Con esta versión preliminar, el
+<a href="{@docRoot}training/articles/keystore.html">proveedor de Android Keystore</a> ya no admite DSA.
+ Aún se admite ECDSA.</p>
+
+<p>Las claves que no requieren cifrado de datos estáticos ya no se eliminarán cuando se restablezca o deshabilite la pantalla de bloqueo seguro (por ejemplo, cuando lo haga el usuario o el administrador del dispositivo).
+ Las claves que requieren el cifrado de datos estáticos se eliminarán durante estos eventos.
+</p>
+
+<h2 id="behavior-network">Cambios en las funciones de red y Wi-Fi</h2>
+
+<p>Esta versión preliminar introduce en las API de redes y Wi-Fi los siguientes cambios en los comportamientos.</p>
+<ul>
+<li>Ahora sus aplicaciones pueden cambiar el estado de los objetos {@link android.net.wifi.WifiConfiguration} solo si usted creó estos objetos.
+ Usted no puede modificar ni eliminar objetos
+{@link android.net.wifi.WifiConfiguration} creados por el usuario o por otras aplicaciones.
+</li>
+<li>
+Anteriormente, si una aplicación forzaba al dispositivo a conectarse a una red Wi-Fi específica utilizando
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} con la configuración
+{@code disableAllOthers=true}, el dispositivo se desconectaba de otras redes, como los datos móviles.
+ En esta versión preliminar, el dispositivo ya no se desconectará de otras redes como estas. Si {@code targetSdkVersion} de su aplicación es {@code “20”} o inferior, se anclará a la red Wi-Fi seleccionada.
+
+ Si {@code targetSdkVersion} de su aplicación es {@code “21”} o posterior, use las API de redes múltiples (como
+{@link android.net.Network#openConnection(java.net.URL) openConnection()},
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} y el nuevo método
+{@code ConnectivityManager.bindProcessToNetwork()}) para garantizar que el tráfico de su red se envíe a la red seleccionada.
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">Cambios en el servicio de cámara</h2>
+<p>En esta versión preliminar, el modelo para acceder a los recursos compartidos en el servicio de cámara se cambió del modelo de acceso anterior “por orden de llegada” a un modelo de acceso en el que se favorecen los procesos de prioridad alta.
+
+ Los cambios en el comportamiento del servicio incluyen los siguientes:</p>
+<ul>
+<li>El acceso a los recursos del subsistema de la cámara, lo que incluye abrir y configurar un dispositivo de cámara, se concede según la “prioridad” del proceso de la aplicación cliente.
+ Por lo general, los procesos de la aplicación con actividades en primer plano o visibles para el usuario, reciben una prioridad más alta, lo que hace que el uso y la adquisición de recursos de la cámara sean más dependientes.
+
+</li>
+<li>Los clientes con cámara activa para aplicaciones de menor prioridad pueden ser “expulsados” cuando una aplicación de mayor prioridad intenta utilizar la cámara.
+ En la API {@link android.hardware.Camera} obsoleta, esto hace que se llame al método
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} para el cliente expulsado.
+
+ En la API {@link android.hardware.camera2 Camera2}, esto hace que se llame al método
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
+para el cliente expulsado.</li>
+<li>En los dispositivos con hardware de cámara correcto, distintos procesos de la aplicación pueden abrir y utilizar de forma independiente dispositivos de cámara separados al mismo tiempo.
+ Sin embargo, ahora el servicio de cámara detecta y no permite los casos de uso de procesos múltiples, donde el acceso simultáneo genera una degradación considerable del rendimiento o de las capacidades de cualquiera de los dispositivos de cámara abiertos.
+
+ Este cambio puede generar “expulsiones” de clientes de menor prioridad, incluso cuando ninguna otra aplicación esté intentando acceder directamente al mismo dispositivo de cámara.
+
+
+</li>
+<li>
+Cambiar el usuario actual provoca que se expulsen los clientes con cámara activa en las aplicaciones que pertenecen a la cuenta de usuario anterior.
+ El acceso a la cámara se limita a perfiles de usuario que pertenecen al usuario actual del dispositivo. En la práctica, esto significa que una cuenta de “invitado”, por ejemplo, no podrá abandonar los procesos en ejecución que utilicen el subsistema de la cámara cuando el usuario haya cambiado a otra cuenta.
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">Tiempo de ejecución de ART</h2>
+<p>El tiempo de ejecución de ART ahora implementa correctamente reglas de acceso para el método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()}. Este cambio soluciona el problema que ocurría con Dalvik, que comprobaba las reglas de acceso incorrectamente en las versiones anteriores. Si su aplicación utiliza el método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} y usted desea invalidar comprobaciones de acceso, llame al método
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} con el parámetro de entrada configurado en {@code true}.
+
+
+
+ Si su aplicación utiliza la
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">biblioteca AppCompat versión 7</a> o la
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">biblioteca RecyclerView versión 7</a>, debe actualizar su aplicación para utilizar las versiones más recientes de estas bibliotecas.
+ De lo contrario, asegúrese de que las clases personalizadas a las que se haga referencia desde el XML estén actualizadas, de manera que se pueda acceder a sus constructores de clases.
+</p>
+
+<p>Esta versión preliminar actualiza el comportamiento del vinculador dinámico. El vinculador dinámico ahora entiende la diferencia entre {@code soname} de una biblioteca y su ruta de acceso (<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+error público 6670</a>), y ahora se implementa la búsqueda por {@code soname}.
+
+
+ Las aplicaciones que anteriormente funcionaban y que tenían entradas {@code DT_NEEDED} incorrectas (generalmente, rutas absolutas en el sistema de archivo del equipo de compilación) pueden generar error al cargarse.
+</p>
+
+<p>Ahora se implementa correctamente la marca {@code dlopen(3) RTLD_LOCAL}. Tenga en cuenta que
+{@code RTLD_LOCAL} es lo predeterminado, por lo que se verán afectadas las llamadas a {@code dlopen(3)} que no utilizaron explícitamente
+{@code RTLD_LOCAL} (salvo que su aplicación haya usado {@code RTLD_GLOBAL} explícitamente). Con
+{@code RTLD_LOCAL}, los símbolos no estarán disponibles para las bibliotecas cargadas por llamadas posteriores a
+{@code dlopen(3)} (a diferencia de lo que sucede al hacer referencia mediante entradas {@code DT_NEEDED}).</p>
+</p>
+
+<h2 id="behavior-apk-validation">Validación de APK</h2>
+<p>Ahora la plataforma realiza validaciones más estrictas de APK. El APK se considera dañado si un archivo está declarado en el manifiesto, pero no está presente en el APK en sí.
+ Si se elimina algún contenido, se debe volver a firmar el APK.
+</p>
+
+<h2 id="behavior-afw">Cambios en Android for Work</h2>
+<p>Esta versión preliminar incluye los siguientes cambios en los comportamientos para Android for Work:</p>
+<ul>
+<li><strong>Contactos de trabajo en contextos personales:</strong> Ahora, el registro de llamadas de Google Dialer muestra los contactos de trabajo cuando el usuario ve las llamadas anteriores. Si se configura {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} en {@code true}, se ocultan los contactos de perfiles de trabajo en el registro de llamadas de Google Dialer.
+
+
+ Los contactos de trabajo se pueden mostrar junto con los contactos personales en los dispositivos a través de Bluetooth solo si usted configura {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} en {@code false}.
+
+ De forma predeterminada, se configura en {@code true}.
+
+</li>
+<li><strong>Eliminación de configuraciones de Wi-Fi:</strong> Las configuraciones de Wi-Fi agregadas por un propietario de perfil (por ejemplo, al llamar al método
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}) ahora se borran si se elimina ese perfil de trabajo.
+</li>
+<li><strong>Bloqueo de configuraciones de Wi-Fi:</strong> El usuario ya no puede modificar ni eliminar las configuraciones de Wi-Fi creadas por un propietario activo del dispositivo.
+ El usuario aún puede crear y modificar sus propias configuraciones de Wi-Fi, siempre que no se haya definido la constante {@link android.os.UserManager}
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} para ese usuario.
+</li>
+<li><strong>Descarga de Work Policy Controller mediante la incorporación de una cuenta de Google:</strong> Cuando una cuenta de Google que requiere gestión a través de una aplicación de Work Policy Controller (WPC) se agrega a un dispositivo fuera de un contexto administrado, el flujo de incorporación de la cuenta ahora le pide al usuario que instale el WPC apropiado. Este comportamiento también se aplica a las cuentas agregadas mediante
+<strong>Settings > Accounts</strong> en el asistente para instalación inicial del dispositivo.
+
+
+</li>
+<li><strong>Cambios en comportamientos específicos de la API DevicePolicyManager:</strong>
+Llamar al método {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+afecta la cámara solo del usuario que lo llama; llamarlo desde el perfil administrado no afecta las aplicaciones de cámara que se ejecutan en el usuario principal.
+ Asimismo, el método
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+ahora se encuentra disponible para propietarios de perfiles, además de propietarios de dispositivos. Un propietario de perfil puede configurar las siguientes restricciones de protección de seguridad:
+
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} y
+ {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, que afectan las configuraciones de protección de seguridad para el usuario primario del perfil.
+</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, que solo afecta las notificaciones generadas por aplicaciones en el perfil administrado.
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/es/preview/features/runtime-permissions.jd b/docs/html-intl/intl/es/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..15bd954
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=Permisos
+page.tags=recursos de la versión preliminar, androidm
+page.keywords=permisos, tiempo de ejecución, vista preliminar
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Quickview</h2>
+ <ul>
+ <li>Si su aplicación tiene como destino el SDK de la versión preliminar de Android M, se solicitará a los usuarios que concedan permisos durante el tiempo de ejecución, en lugar de durante la instalación.
+</li>
+ <li>Los usuarios pueden cancelar los permisos en cualquier momento desde la pantalla Settings de la aplicación.
+</li>
+ <li>La aplicación necesita controlar los permisos cada vez que se ejecuta.
+</li>
+ </ul>
+
+ <h2>Contenido del documento</h2>
+ <ol>
+ <li><a href="#overview">Información general</a></li>
+ <li><a href="#coding">Codificación para permisos de tiempo de ejecución</a></li>
+ <li><a href="#testing">Prueba de permisos de tiempo de ejecución</a></li>
+ <li><a href="#best-practices">Mejores prácticas</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ M Developer Preview introduce un nuevo modelo de permisos de la aplicación que facilita a los usuarios el proceso de instalación y actualización de aplicaciones.
+ Si una aplicación que se ejecuta en la versión preliminar de Android M es compatible con el nuevo modelo de permisos, el usuario no tiene que conceder ningún permiso al instalar o actualizar la aplicación. En su lugar, la aplicación solicitará los permisos a medida que los vaya necesitado y el sistema mostrará al usuario un diálogo en el que le solicitará los permisos necesarios.
+
+
+
+
+</p>
+
+<p>
+ Si la aplicación es compatible con el nuevo modelo de permisos, podrá instalarse y ejecutarse en los dispositivos con versiones anteriores de Android, utilizando el modelo de permisos anterior en esos dispositivos.
+
+
+</p>
+
+<h2 id="overview">
+ Información general
+</h2>
+
+<p>
+ En M Developer Preview, la plataforma introduce un nuevo modelo
+de permisos de la aplicación. A continuación, se presenta un resumen de los componentes principales de este nuevo modelo:
+</p>
+
+<ul>
+ <li>
+ <strong>Declaración de los permisos:</strong> Al igual que en las plataformas anteriores de Android, la aplicación declara todos los permisos que necesita en el manifiesto.
+
+ </li>
+
+ <li>
+ <strong>Grupos de permisos:</strong> Según su función, los permisos se dividen en
+<em>grupos de permisos</em>. Por ejemplo, el grupo de permisos
+<code>CONTACTS</code> contiene permisos para leer y escribir los contactos y la información de perfil del usuario.
+
+ </li>
+
+ <li>
+ <p><strong>Permisos limitados concedidos durante la instalación:</strong> Cuando el usuario instala o actualiza la aplicación, el sistema le concede a la aplicación todos los permisos que la aplicación solicita que corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
+
+
+ Por ejemplo, los permisos para la alarma y los permisos de intento corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}, por lo que se conceden automáticamente durante la instalación.
+
+ </p>
+
+ <p>El sistema puede concederle a la aplicación permisos de firma y de sistema, como se especifica en la sección <a href="#system-apps">Permisos de firma y de sistema de la aplicación</a>.
+
+ Al usuario <em>no</em> se le solicitará conceder ningún permiso durante la instalación.
+</p>
+ </li>
+
+ <li>
+ <strong>Solicitud de permisos al usuario durante el tiempo de ejecución:</strong> Cuando la aplicación solicita un permiso, el sistema le muestra al usuario un diálogo y luego llama a la función de devolución de llamada de la aplicación para notificarle si el permiso se otorgó.
+
+ Si el usuario concede un permiso, la aplicación recibe todos los permisos del área funcional de dicho permiso, los cuales fueron declarados en el manifiesto de la aplicación.
+
+
+ </li>
+
+</ul>
+
+<p>
+ Este modelo de permisos cambia la forma en la que la aplicación se comporta para características que requieren permisos.
+ A continuación, se presenta un resumen de las prácticas de desarrollo que debe seguir para ajustarse a este modelo:
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>Siempre compruebe los permisos:</strong> Siempre que una aplicación necesite realizar una acción que requiere algún permiso, primero debe comprobar si ya tiene otorgado ese permiso.
+
+ En caso de no tenerlo, solicitará que se le otorgue ese permiso.
+
+ </li>
+
+ <li>
+ <strong>Administre la falta de permisos correctamente:</strong> Si la aplicación no recibe un permiso adecuado, deberá administrar la falla sin errores.
+
+ Por ejemplo, si se necesita el permiso solo para una característica añadida, la aplicación puede desactivar esa característica.
+ Si el permiso es fundamental para que la aplicación funcione, la aplicación podrá desactivar toda su funcionalidad e informar al usuario que se deben conceder dichos permisos.
+
+
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>Figura 1</strong> Pantalla de permisos en Settings de la aplicación.
+ </p>
+ </div>
+
+ <li>
+ <strong>Los permisos son revocables:</strong> Los usuarios pueden revocar los permisos en cualquier momento.
+ Si un usuario desactiva los permisos de una aplicación, la aplicación <em>no</em> recibe ningún aviso.
+ Nuevamente, la aplicación deberá verificar que cuenta con los permisos necesarios antes de realizar cualquier acción restringida.
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Nota:</strong> Si una aplicación tiene como destino M Developer Preview, <em>debe</em> utilizar el nuevo modelo de permisos.
+
+</p>
+
+<p>
+ A partir del lanzamiento de M Developer Preview, no todas las aplicaciones de Google implementarán por completo el nuevo modelo de permisos.
+ Google actualiza estas aplicaciones durante el transcurso de M Developer Preview para respetar adecuadamente las configuraciones de alternancia de los permisos.
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> Si la aplicación cuenta con su propia superficie de API, no transmita permisos sin antes asegurarse de que el iniciador de la llamada cuente con los permisos requeridos para acceder a esa información.
+
+
+</p>
+
+<h3 id="system-apps">
+ Permisos de las aplicaciones de firma y de sistema
+</h3>
+
+<p>
+ Generalmente, cuando el usuario instala una aplicación, el sistema solo otorga a la aplicación
+{@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL}. Sin embargo, en ciertas circunstancias, el sistema le concede a la aplicación más permisos:
+
+</p>
+
+<ul>
+ <li>Si una aplicación es parte de la imagen del sistema, la aplicación recibe automáticamente todos los permisos enumerados en el manifiesto.
+
+ </li>
+
+ <li>Si la aplicación solicita permisos en el manifiesto que corresponden a {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} y la aplicación está firmada con el mismo certificado que el de la aplicación que declaró dichos permisos, el sistema le concede a la aplicación que los solicita esos permisos durante la instalación.
+
+
+
+ </li>
+</ul>
+
+<p>
+ En ambos casos, el usuario aún puede revocar los permisos en cualquier momento si accede a la pantalla <strong>Settings</strong> del sistema y selecciona <strong>Apps ></strong>
+
+ <i>app_name</i> <strong>> Permissions</strong>. La aplicación debe seguir controlando los permisos al momento de la ejecución y solicitarlos si fuese necesario.
+
+
+</p>
+
+<h3 id="compatibility">
+ Compatibilidad con modelos anteriores y posteriores
+</h3>
+
+<p>
+ Si una aplicación no tiene como destino M Developer Preview, la aplicación continúa utilizando el modelo de permisos anterior, incluso en dispositivos con la versión preliminar de Android M.
+ Cuando el usuario instala la aplicación, el sistema le solicita al usuario que otorgue todos los permisos enumerados en el manifiesto de la aplicación.
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> En dispositivos que ejecutan M Developer Preview, el usuario puede desactivar los permisos para cualquier aplicación (incluso para aplicaciones heredadas) desde la pantalla Settings de la aplicación.
+
+ Si un usuario desactiva permisos para una aplicación heredada, el sistema desactiva las funciones correspondientes de forma automática.
+ Cuando la aplicación intenta realizar una operación que requiere ese permiso, la operación no generará necesariamente una excepción.
+
+ En su lugar, devolverá un conjunto de datos vacíos, indicará un error o, de lo contrario, mostrará un comportamiento inesperado.
+ Por ejemplo, si realiza una consulta sobre el calendario sin permisos, el método devuelve un conjunto de datos vacíos.
+
+</p>
+
+<p>
+ Si instala una aplicación que utiliza el nuevo modelo de permisos en un dispositivo que no ejecuta la versión preliminar de Android M, el sistema la trata como cualquier otra aplicación: el sistema le pide al usuario, durante la instalación, que conceda los permisos declarados.
+
+
+
+</p>
+
+<p class="note">
+ <strong>Nota:</strong> Para el lanzamiento de la versión preliminar, debe configurar la versión mínima del SDK en M Preview SDK para compilar con la versión del SDK preliminar.
+ Esto significa que no podrá probar dichas aplicaciones en plataformas anteriores durante la versión preliminar para desarrolladores.
+
+
+</p>
+
+<h3 id="perms-vs-intents">Permisos frente a intentos</h3>
+
+<p>
+ En muchas situaciones, puede elegir entre dos formas para que sus aplicaciones realicen una tarea.
+ Puede hacer que su aplicación solicite permiso para realizar la operación por sí misma.
+ De lo contrario, puede hacer que la aplicación utilice un intento para que otra aplicación realice la tarea.
+
+</p>
+
+<p>
+ Por ejemplo, supongamos que su aplicación necesita poder tomar fotografías con la cámara del dispositivo.
+ Su aplicación puede solicitar el permiso
+<code>android.permission.CAMERA</code>, lo que le permite a su aplicación acceder a la cámara directamente.
+ Entonces, su aplicación utilizará las API de la cámara para controlar la cámara y tomar una fotografía.
+ Este enfoque le otorga a su aplicación total control del proceso de fotografía y le permite incorporar la UI de la cámara en su aplicación.
+
+
+</p>
+
+<p>
+ Sin embargo, si no necesita dicho control, puede utilizar {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} para solicitar una imagen.
+ Cuando ejecute el intento, se le solicita al usuario que elija una aplicación de cámara (en caso de que no haya una aplicación de cámara predeterminada) y esa aplicación tomará la fotografía.
+
+ La aplicación de cámara devuelve la fotografía al método {@link
+ android.app.Activity#onActivityResult onActivityResult()} de su aplicación.
+</p>
+
+<p>
+ De manera similar, si necesita realizar una llamada telefónica, acceder a los contactos del usuario, etc., lo puede hacer creando intentos apropiados o puede solicitar los permisos e ingresar directamente a los objetos apropiados.
+
+ Cada enfoque tiene ventajas y desventajas.
+
+</p>
+
+<p>
+ Si utiliza los permisos:
+</p>
+
+<ul>
+ <li>La aplicación posee total control sobre la experiencia del usuario cuando usted realiza la operación.
+ Sin embargo, un control tan amplio complica su tarea, ya que usted deberá diseñar una UI apropiada.
+
+ </li>
+
+ <li>Se le solicita al usuario otorgar el permiso una vez, la primera vez que usted realiza la operación.
+ Luego, su aplicación puede realizar la operación sin requerir interacción adicional por parte del usuario.
+ Sin embargo, si el usuario no concede el permiso (o lo revoca luego), su aplicación queda inhabilitada para realizar la operación.
+
+
+ </li>
+</ul>
+
+<p>
+ Si utiliza un intento:
+</p>
+
+<ul>
+ <li>No debe diseñar la UI para la operación. La aplicación que controla el intento provee la UI. Sin embargo, esto significa que usted no tiene control sobre la experiencia del usuario.
+
+ El usuario podrá interactuar con una aplicación que usted no conoce.
+
+ </li>
+
+ <li>Si el usuario no tiene una aplicación predeterminada para la operación, el sistema le solicita al usuario que elija una aplicación. Si el usuario no designa un controlador predeterminado, es probable que surja un diálogo adicional cada vez que realice la operación.
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">Codificación para permisos de tiempo de ejecución</h2>
+
+<p>
+ Si su aplicación tiene como destino el nuevo M Developer Preview, deberá usar el nuevo modelo de permisos.
+ Esto significa que, además de declarar los permisos necesarios en el manifiesto, también debe comprobar si tiene los permisos de tiempo de ejecución y solicitarlos en caso de no tenerlos.
+
+
+
+</p>
+
+<h3 id="enabling">
+ Habilitar el nuevo modelo de permisos
+</h3>
+
+<p>
+ Para habilitar el nuevo modelo de permisos de M Developer Preview, configure el atributo
+<code>targetSdkVersion</code> de la aplicación en <code>"MNC"</code> y
+<code>compileSdkVersion</code> en <code>"android-MNC"</code>. Al hacerlo, se habilitan todas las características de los nuevos permisos.
+
+</p>
+
+<p>
+ Para el lanzamiento de la versión preliminar, debe establecer <code>minSdkVersion</code> en
+<code>"MNC"</code> para compilar con el SDK preliminar.
+</p>
+
+<h3 id="m-only-perm">
+ Establecer un permiso solo para la versión preliminar de Android M
+</h3>
+
+<p>
+ Puede utilizar el nuevo elemento <code><uses-permission-sdk-m></code> en el manifiesto de la aplicación para indicar que se necesita un permiso solo para M Developer Preview.
+ Si declara un permiso de esta manera, cuando la aplicación se instale en un dispositivo anterior, el sistema no le solicitará al usuario el permiso ni se lo otorgará a la aplicación. Al usar el elemento <code><uses-permission-sdk-m></code>, puede añadir nuevos permisos a las versiones actualizadas de su aplicación sin forzar a los usuarios a otorgar permisos cuando instalen la actualización.
+
+
+
+
+
+
+</p>
+
+<p>
+ Si la aplicación se ejecuta en un dispositivo con M Developer Preview,
+<code><uses-permission-sdk-m></code> se comporta al igual que
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
+ El sistema no le solicita al usuario que otorgue ningún permiso al instalar la aplicación y la aplicación solicita los permisos a medida que se necesiten.
+
+</p>
+
+<h3 id="prompting">
+ Solicitar permisos
+</h3>
+
+<p>
+ Si su aplicación utiliza el nuevo modelo de permisos de M Developer Preview, no se le pedirá al usuario que otorgue todos los permisos cuando la aplicación se ejecute por primera vez en un dispositivo con la versión preliminar de Android M.
+
+ En su lugar, su aplicación solicita los permisos a medida que los necesita.
+ Cuando su aplicación solicita un permiso, el sistema le muestra un diálogo al usuario.
+
+</p>
+
+<p>
+ Si su aplicación se ejecuta en un dispositivo con SDK 22 o anterior, la aplicación utiliza el modelo de permisos anterior.
+ Cuando el usuario instala la aplicación, se le solicita que otorgue todos los permisos que la aplicación requiere en su manifiesto, excepto aquellos permisos marcados con <code><uses-permission-sdk-m></code>.
+
+
+</p>
+
+<h4 id="check-platform">Controlar en qué plataforma se ejecuta la aplicación</h4>
+
+<p>
+ Este modelo de permisos es compatible solamente con dispositivos que ejecutan M Developer Preview.
+ Antes de llamar a cualquiera de estos métodos, la aplicación debe verificar en qué plataforma se está ejecutando y, para hacerlo, se controla el valor de {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME}.
+
+ Si el dispositivo ejecuta M Developer Preview,
+{@link android.os.Build.VERSION#CODENAME CODENAME} es <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Controlar si la aplicación cuenta con los permisos necesarios</h4>
+
+<p>Cuando el usuario intenta realizar algo que requiere un permiso, la aplicación controla si ya tiene el permiso para realizar esa operación.
+ Para hacerlo, la aplicación llama a <code>Context.checkSelfPermission(
+
+<i>permission_name</i>)</code>. La aplicación debe realizar este control incluso si sabe que el usuario ya ha concedido ese permiso, ya que el usuario puede revocar los permisos de una aplicación en cualquier momento.
+
+
+ Por ejemplo, si un usuario quiere usar una aplicación para tomar una fotografía, la aplicación llama a <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.
+
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>Tabla 1.</strong> Permisos y grupo de permisos.</p>
+<table>
+ <tr>
+ <th scope="col">Grupo de permisos</th>
+ <th scope="col">Permisos</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">Solicitar permisos si se necesitan</h4>
+
+<p>Si la aplicación no posee los permisos que necesita, llama al método
+<code>Activity.requestPermissions(String[], int)</code> para solicitar el permiso o los permisos apropiados.
+ La aplicación pasa el permiso o los permisos que necesita y un “código de solicitud” entero.
+
+ Este método funciona de manera asincrónica: realiza la devolución inmediatamente y cuando el usuario responde a la ventana de diálogo, el sistema llama al método de devolución de llamada de la aplicación con los resultados, y pasa el mismo “código de solicitud” que pasó la aplicación a
+<code>requestPermissions()</code>.
+
+</p>
+
+ <p>El siguiente código verifica si la aplicación tiene permisos para leer los contactos del usuario y solicita los permisos de ser necesario:
+</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">Administrar la respuesta a la solicitud de permisos</h4>
+
+<p>
+ Cuando una aplicación solicita permisos, el sistema le muestra al usuario una ventana de diálogo.
+ Cuando el usuario responde, el sistema invoca
+<code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+ de su aplicación y le transfiere la respuesta del usuario. Su aplicación necesita invalidar ese método. La devolución de llamada pasa el mismo código de solicitud que usted pasó a <code>requestPermissions()</code>.
+
+ Por ejemplo, si una aplicación solicita acceso <code>READ_CONTACTS</code>, es posible que tenga el siguiente método de devolución de llamada:
+
+
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>Si el usuario concede un permiso, el sistema le otorga a la aplicación todos los permisos enumerados en el manifiesto para esa área funcional.
+ Se deben tomar acciones apropiadas si el usuario rechaza la solicitud.
+ Por ejemplo, usted podría desactivar cualquier acción del menú que dependa de este permiso.
+
+ </li>
+</p>
+
+<p>
+ Cuando el sistema le solicita al usuario que otorgue un permiso, el usuario tiene la opción de indicarle al sistema que no solicite ese permiso de nuevo.
+ En ese caso, cuando la aplicación utiliza <code>requestPermissions()</code> para solicitar ese permiso, el sistema rechaza la solicitud inmediatamente.
+
+ En este caso, el sistema llama a su <code>onRequestPermissionsResult()</code> de la misma manera en que lo haría si el usuario hubiese rechazado explícitamente su solicitud nuevamente.
+
+ Por esta razón, su aplicación no puede asumir que se ha llevado a cabo algún tipo de interacción con el usuario.
+
+</p>
+
+<h2 id="testing">Prueba de permisos de tiempo de ejecución</h2>
+
+
+<p>
+ Si su aplicación tiene como destino M Developer Preview, debe probar que administre los permisos correctamente.
+ No debe asumir que su aplicación tiene algún permiso en particular cuando se ejecuta.
+ Cuando la aplicación se ejecuta por primera vez, es muy probable que no tenga permisos y el usuario puede revocar o reestablecer los permisos en cualquier momento.
+
+
+</p>
+
+<p>
+ Debe probar su aplicación para asegurarse de que funciona correctamente en todas las situaciones de permisos.
+ Con el SDK de la versión preliminar de Android M, hemos brindado nuevos comandos <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (adb)</a> que le permitirán probar su aplicación con cualquier configuración de permisos que necesite probar.
+
+
+
+</p>
+
+<h3>
+ Nuevas opciones y comandos adb
+</h3>
+
+<p>
+ Las herramientas de plataforma del SDK de la versión preliminar de Android M contienen varios comandos nuevos que le permiten probar la manera en que su aplicación administra los permisos.
+
+</p>
+
+<h4>
+ Instalar con permisos
+</h4>
+
+<p>
+ Puede utilizar la nueva opción <code>-g</code> del comando <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, que instala la aplicación y concede todos los permisos enumerados en el manifiesto de la aplicación:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ Conceder y revocar permisos
+</h4>
+
+<p>
+ Puede utilizar los comandos ADB nuevos <a href="{@docRoot}tools/help/adb.html#pm">package manager (pm)</a> para conceder y revocar permisos a una aplicación instalada. Esta funcionalidad puede resultar útil para pruebas automáticas.
+
+
+</p>
+
+<p>
+ Para conceder un permiso, utilice el comando <code>grant</code> de package manager:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ Por ejemplo, para conceder el paquete de permisos com.example.myapp para grabar audio utilice este comando:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ Para revocar un permiso, utilice el comando <code>revoke</code> de package manager:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">Mejores prácticas</h2>
+
+<p>
+ El nuevo modelo de permisos brinda a los usuarios una experiencia más fluida y les facilita la instalación de aplicaciones, además de hacerlos sentir cómodos con las actividades de sus aplicaciones.
+
+ Sugerimos las siguientes mejores prácticas para obtener el mayor beneficio del nuevo modelo.
+
+</p>
+
+
+<h3 id="bp-what-you-need">Solicite solo los permisos que necesite</h3>
+
+<p>
+ Cada vez que solicite un permiso, usted obliga al usuario a tomar una decisión.
+ La funcionalidad de su aplicación se verá reducida si el usuario rechaza la solicitud.
+ Debe minimizar la cantidad de veces que realiza estas solicitudes.
+</p>
+
+<p>
+ Por ejemplo, a menudo, su aplicación puede obtener la funcionalidad necesaria a través de un <a href="{@docRoot}guide/components/intents-filters.html">intento</a> en lugar de una solicitud de permiso.
+
+ Si su aplicación necesita tomar fotografías con la cámara del teléfono, la aplicación puede utilizar un intento {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE}.
+ Cuando su aplicación ejecuta el intento, el sistema le solicita al usuario que elija una aplicación para la cámara que ya está instalada a fin de tomar la fotografía.
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ No abrume al usuario
+</h3>
+
+<p>
+ Si expone al usuario a muchas solicitudes de permisos al mismo tiempo, lo abrumará y hará que deje de usar su aplicación. Por el contrario, debe pedir permisos en la medida que los necesite.
+
+
+</p>
+
+<p>
+ A veces, uno o más permisos pueden ser absolutamente necesarios para la aplicación. En ese caso, es recomendable pedir todos los permisos no bien se inicie la aplicación.
+
+ Por ejemplo, si crea una aplicación de fotografía, la aplicación necesitará acceso a la cámara del dispositivo.
+ Cuando el usuario inicie la aplicación por primera vez, no se sorprenderá si la aplicación le solicita permiso para usar la cámara.
+
+ Sin embargo, si la misma aplicación además tuviese una característica para compartir fotografías con los contactos del usuario, <em>no</em> solicite ese permiso la primera vez que se ejecute.
+
+ En su lugar, espere hasta que el usuario utilice la característica “compartir” para solicitar el permiso en ese momento.
+
+</p>
+
+<p>
+ Si su aplicación proporciona un tutorial, se recomienda que se pidan los permisos esenciales de la aplicación al final del tutorial.
+
+</p>
+
+<h3 id="bp-explain">
+ Explique por qué se necesitan los permisos
+</h3>
+
+<p>
+ El diálogo de permisos que muestra el sistema cuando llama a
+ <code>requestPermissions()</code> informa qué permisos necesita su aplicación pero no establece el motivo.
+ A veces, el usuario puede confundirse.
+ Es una buena idea explicarle al usuario los motivos por los que la aplicación necesita esos permisos antes de llamar a <code>requestPermissions()</code>.
+
+</p>
+
+<p>
+ Por ejemplo, una aplicación de fotografía puede solicitar servicios de ubicación para añadir una etiqueta geográfica a las fotografías.
+ Es posible que un usuario típico no sepa que una fotografía puede contener información sobre la ubicación y se confundiría si una aplicación de fotografía solicita la ubicación.
+
+ En este caso, es recomendable que la aplicación le informe al usuario acerca de esta característica <em>antes</em> de llamar a
+<code>requestPermissions()</code>.
+
+</p>
+
+<p>
+ Una forma de hacerlo es incorporar estas solicitudes en el tutorial de la aplicación. El tutorial puede mostrar todas las características de la aplicación, una por vez, y mientras lo hace explicar los permisos que son necesarios.
+
+ Por ejemplo, el tutorial de la aplicación de fotografía puede mostrar la característica “compartir fotografías con contactos” y luego explicarle al usuario que debe otorgar permisos para que la aplicación vea los contactos del usuario.
+
+
+ La aplicación puede entonces llamar a <code>requestPermissions()</code> para solicitarle al usuario ese acceso.
+ Por supuesto, no todos los usuarios siguen el tutorial, por lo que aun así debe controlar y solicitar los permisos durante el funcionamiento normal de la aplicación.
+
+
+</p>
diff --git a/docs/html-intl/intl/es/preview/overview.jd b/docs/html-intl/intl/es/preview/overview.jd
new file mode 100644
index 0000000..49cc3d3
--- /dev/null
+++ b/docs/html-intl/intl/es/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Información general del programa
+page.metaDescription=Bienvenido a Android M Developer Preview, el programa que le brinda todo lo que necesita para probar y optimizar sus aplicaciones para la próxima versión de Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Bienvenido a <strong>Android M Developer Preview</strong>, el programa que le brinda todo lo que necesita para probar y optimizar sus aplicaciones para la próxima versión de Android.
+
+ Es gratis y puede comenzar a utilizarlo ahora mismo. Solo tiene que descargar las herramientas de M Developer Preview.
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ Imágenes del sistema emulador y de hardware
+ </h5>
+
+ <p>
+ Ejecute y pruebe sus aplicaciones en Nexus 5, 6, 9 y Player (para TV), además del emulador.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Último código de la plataforma
+ </h5>
+
+ <p>
+ Durante la versión preliminar, ofreceremos múltiples actualizaciones, por lo que usted realizará la prueba comparando los últimos cambios de la plataforma.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Actualizaciones vía OTA
+ </h5>
+
+ <p>
+ Luego de actualizar su dispositivo a la versión preliminar inicial, usted podrá obtener actualizaciones por red inalámbrica (over-the-air, OTA).
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Nuevos comportamientos y capacidades
+ </h5>
+
+ <p>
+ Inicie el funcionamiento con anticipación para admitir los comportamientos de la nueva plataforma como el nuevo modelo de permisos de tiempos de ejecución y las opciones de ahorro de energía.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Ventana de prioridad para los problemas informados por los desarrolladores
+ </h5>
+
+ <p>
+ Durante las primeras semanas, daremos prioridad a los problemas informados por los desarrolladores; por lo tanto, realice las pruebas y envíe sus comentarios lo antes posible.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Comentarios y soporte
+ </h5>
+
+ <p>
+ Infórmenos los problemas y envíenos comentarios a través de nuestro <a href="https://code.google.com/p/android-developer-preview/">seguimiento de problemas</a>.
+ Póngase en contacto con otros desarrolladores de la comunidad <a href="http://g.co/dev/AndroidMDevPreview">M Developer Community</a>.
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ Escala de tiempo y actualizaciones
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M Developer Preview estará disponible a partir del 28 de mayo hasta la versión final del SDK de Android M, que lanzaremos al poco tiempo del lanzamiento público durante el tercer trimestre de 2015.
+
+
+</p>
+
+<p>
+ En momentos clave del desarrollo, lanzaremos actualizaciones para sus dispositivos de prueba.
+ Los momentos clave tentativos son los siguientes:
+</p>
+
+<ul>
+ <li>
+ <strong>Preview 1</strong> (lanzamiento inicial de la versión preliminar, fines de mayo)
+ </li>
+
+ <li>
+ <strong>Preview 2</strong> (fines de junio, comienzos de julio)
+ </li>
+
+ <li>
+ <strong>Preview 3</strong> (casi la versión final, a fines de julio)
+ </li>
+</ul>
+
+<p>
+ Estas actualizaciones terminan con el <strong>SDK final</strong> (más adelante durante el tercer trimestre), lo que proporcionará tanto las API oficiales para la nueva versión de Android como los comportamientos y las características finales del sistema.
+
+
+</p>
+
+<p>
+ A medida que usted prueba y desarrolla en Android M, le recomendamos que <strong>mantenga su entorno de desarrollo actualizado</strong> a medida que se lanzan las actualizaciones de la versión preliminar.
+
+ Para que el proceso sea más fácil, lanzaremos <strong>actualizaciones OTA</strong> para los dispositivos que ya hayan sido actualizados a una compilación de la versión preliminar y brindaremos imágenes del sistema que puede descargar y actualizar manualmente.
+
+
+</p>
+<p class="note">
+ <strong>Nota:</strong> El SDK final y las imágenes del sistema no se pueden proporcionar vía OTA y deberán <strong>actualizarse manualmente</strong> en sus dispositivos de prueba.</strong>
+
+
+</p>
+
+<p>
+ Le informaremos cuando las actualizaciones de la versión preliminar se encuentren disponibles a través del blog de Android para desarrolladores (<a href="http://android-developers.blogspot.com/">Android Developers Blog</a>), de este sitio y de la comunidad de desarrolladores <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a>.
+
+
+</p>
+
+<h2 id="preview_tools">
+ ¿Qué ofrece la versión preliminar?
+</h2>
+
+<p>
+ M Developer Preview incluye todo lo que necesita para probar sus aplicaciones actuales en una variedad de tamaños de pantalla, de tecnologías de redes, de conjuntos de chip CPU/GPU y de arquitecturas de hardware.
+
+
+</p>
+
+<h4>
+ Herramientas del SDK
+</h4>
+
+<p>
+ Estos componentes se pueden descargar mediante SDK Manager en <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>:
+</p>
+
+<ul>
+ <li><strong>Herramientas del SDK</strong> de M Developer Preview
+ </li>
+
+ <li><strong>Imagen del sistema emulador</strong> (32-bit y 64-bit) de M Developer Preview
+
+ </li>
+
+ <li><strong>Imagen del sistema emulador para Android TV</strong> (32-bit) de M Developer Preview
+
+ </li>
+</ul>
+
+<h4>
+ Imágenes del sistema de hardware
+</h4>
+
+<p>
+ Puede descargar estas imágenes del sistema de hardware para dispositivos Nexus desde la <a href="download.html">página de Descargas</a>:
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE) imagen del sistema del dispositivo “hammerhead”
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> imagen del sistema del dispositivo “shamu”
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi) imagen del sistema del dispositivo “volantis”
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV) imagen del sistema del dispositivo “fugu”
+ </li>
+</ul>
+
+<h4>
+ Documentación y código de muestra
+</h4>
+
+<p>
+ Estos recursos de documentación lo ayudan a obtener información sobre la versión preliminar:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">Configurar el SDK</a>: contiene instrucciones paso a paso para comenzar.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Guía de prueba</a> y <a href="behavior-changes.html">Cambios en los comportamientos</a>: le indican las áreas más importantes que debe probar.
+ </li>
+
+ <li>Documentación sobre las nuevas API, lo que incluye <a href="api-overview.html">Información general de la API</a>, <a href="{@docRoot}preview/download.html#docs">Referencia de la API</a> que se puede descargar y guías detalladas para desarrolladores sobre características clave como <a href="{@docRoot}preview/features/runtime-permissions.html">permisos</a>, <a href="{@docRoot}preview/backup/index.html">copias de seguridad de la aplicación</a>, entre otras.
+
+
+
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">Código de ejemplo</a>: indica cómo admitir permisos y otras características nuevas.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">Notas de la versión</a> para la versión actual de M Developer Preview, lo que incluye notas sobre los cambios e informes de diferencias.
+
+ </li>
+</ul>
+
+<h4>
+ Recursos de soporte
+</h4>
+
+<p>
+ Utilice los siguientes recursos de soporte durante el proceso de prueba y desarrollo en M Developer Preview:
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">El seguimiento de problemas de M Developer Preview</a> es su<strong> canal principal de comentarios.</strong>
+
+ A través de este seguimiento de problemas, usted puede informarnos errores o problemas de rendimiento, y enviarnos comentarios generales.
+ También puede buscar <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">problemas recurrentes</a> y encontrar soluciones alternativas detalladas.
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a> es una comunidad en Google+ donde usted puede <strong>contactarse con otros desarrolladores</strong> que estén trabajando con Android M. Puede compartir comentarios o ideas, o encontrar respuestas a sus dudas sobre Android M.
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Selección del destino, API preliminares y publicación
+</h2>
+
+<p>
+ Android M Developer Preview es una versión solo para desarrollo y <strong>no tiene un nivel de API estándar</strong>.
+ Si quiere darse de baja de los comportamientos de compatibilidad para probar su aplicación (lo que es muy recomendado), puede elegir como destino M Developer Preview estableciendo <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> de su aplicación como <code>“MNC”</code>.
+
+
+
+</p>
+
+<p>
+ Android M Developer Preview ofrece <strong>API preliminares</strong>
+ — las API no serán oficiales hasta que se lance el SDK final, lo que actualmente está planeado para el tercer trimestre de 2015.
+ Esto quiere decir que surgirán <strong>cambios menores en la API</strong> con el tiempo, particularmente durante las primeras semanas del programa.
+
+ Con cada actualización de Android M Developer Preview, proporcionaremos un resumen con los cambios realizados.
+
+</p>
+
+<p class="note">
+ Tenga en cuenta que aunque las API preliminares pueden modificarse, los comportamientos del sistema subyacente, como los permisos de tiempo de ejecución y las opciones de ahorro de energía, se mantienen estables y disponibles para cualquier prueba inmediata.
+
+
+</p>
+
+<p>
+ En cuanto a la publicación, Google Play <strong>no permite que se publiquen aplicaciones que tienen como destino M Developer Preview</strong>.
+ Una vez que el SDK final de Android M esté disponible, podrá seleccionar como destino el nivel de API oficial de Android M y publicar su aplicación en Google Play.
+
+ Mientras tanto, si desea distribuir una aplicación con Android M como destino a otros evaluadores, lo puede hacer por correo electrónico o mediante descarga directa desde su sitio.
+
+
+</p>
+
+<h2 id="get_started">
+ ¿Cómo comenzar?
+</h2>
+
+<p>
+ Para comenzar a probar su aplicación:
+</p>
+
+<ol>
+ <li>Revise el artículo <a href="{@docRoot}preview/api-overview.html">Información general de la API</a> y <a href="{@docRoot}preview/behavior-changes.html">Cambios en los comportamientos</a> para obtener una idea sobre las novedades y cómo estas pueden afectar sus aplicaciones.
+
+ En especial, infórmese sobre el nuevo modelo de <a href="{@docRoot}preview/features/runtime-permissions.html">permisos de tiempo de ejecución</a>, las opciones de ahorro de energía y las copias de seguridad automáticas.
+
+
+ </li>
+
+ <li>Configure su entorno siguiendo las instrucciones para <a href="{@docRoot}preview/setup-sdk.html">Configurar el SDK de la versión preliminar</a> y configurar los dispositivos de prueba.
+
+
+ </li>
+
+ <li>Siga las <a href="https://developers.google.com/android/nexus/images">instrucciones de actualización</a> para actualizar la última imagen del sistema del desarrollador de Android M para Nexus 5, 6, 9 y Player.
+
+ Cuando haya actualizado su dispositivo de desarrollo, recibirá las actualizaciones de la versión preliminar mediante actualizaciones OTA.</a>
+
+ </li>
+
+ <li>Descargue la <a href="{@docRoot}preview/download.html#docs">Referencia de la API de M Preview</a> y los <a href="{@docRoot}preview/samples.html">Ejemplos de M Preview</a> para obtener más información sobre las nuevas características de la API y sobre cómo utilizarlas en su aplicación.
+
+
+
+ </li>
+
+ <li>Únase a la comunidad <a href="http://g.co/dev/AndroidMDevPreview">Android M Developer Community</a> para recibir las últimas noticias y para contactarse con otros desarrolladores que estén trabajando con la nueva plataforma.
+
+
+ </li>
+</ol>
+
+<p>
+ ¡Agradecemos su participación en el programa Android M Developer Preview!
+</p>
diff --git a/docs/html-intl/intl/ja/preview/api-overview.jd b/docs/html-intl/intl/ja/preview/api-overview.jd
new file mode 100644
index 0000000..2c0816b
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=API の概要
+page.keywords=プレビュー,sdk,互換性
+page.tags=previewresources, androidm sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本書の内容
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">詳細を表示</span>
+ <span class="less" style="display:none">詳細を非表示</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">アプリのリンク機能</a></li>
+ <li><a href="#backup">アプリの自動バックアップ</a></li>
+ <li><a href="#authentication">認証</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">指紋認証</a></li>
+ <li><a href="#confirm-credential">資格情報の確認</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">ダイレクト シェア</a></li>
+ <li><a href="#voice-interactions">音声インタラクション</a></li>
+ <li><a href="#assist">Assist API</a></li>
+ <li><a href="#notifications">通知</a></li>
+ <li><a href="#bluetooth-stylus">Bluetooth スタイラスのサポート</a></li>
+ <li><a href="#ble-scanning">Bluetooth Low Energy のスキャンの改善</a></li>
+ <li><a href="#hotspot">アクセス ポイント2.0 リリース 1 のサポート</a></li>
+ <li><a href="#4K-display">4K ディスプレイ モード</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">テーマ化可能な ColorStateLists</a></li>
+ <li><a href="#audio">オーディオ機能</a></li>
+ <li><a href="#video">ビデオ機能</a></li>
+ <li><a href="#camera">カメラ機能</a>
+ <ol>
+ <li><a href="#flashlight">Flashlight API</a></li>
+ <li><a href="#reprocessing">カメラの再処理</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Android for Work の機能</a></li>
+</ol>
+
+<h2>API の変更点</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API レベル 22 から M Preview»</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview では、ユーザーやアプリ開発者に Android プラットフォームの次期リリースの新機能をいち早く試していただくことができます。
+
+このドキュメントでは、いくつかの注目すべき API の概要について説明します。</p>
+
+<p>M Developer Preview は、<strong>Developer の早期導入者</strong>と<strong>テスター</strong>を対象としています。
+是非
+<a href="{@docRoot}preview/setup-sdk.html">M Developer Preview を試して</a>フィードバックをご提供ください。あなたのご意見が、Android フレームワークの方向性を決定する上で貴重な情報になります。
+
+</p>
+
+<p class="caution"><strong>注意:</strong> M Developer Preview を使用したアプリは、Google Play ストアには公開しないでください。
+</p>
+
+<p class="note"><strong>注</strong>: このドキュメントには、まだ <a href="{@docRoot}">developer.android.com</a> のリファレンス マテリアルにないクラスやメソッドが多数登場します。
+このドキュメントでは、API エレメントは {@code code style} 形式で記載されています(ハイパーリンクなし)。
+これらのエレメントに関する API ドキュメント(準備段階)については、<a href="{@docRoot}preview/download.html#docs">プレビューのリファレンス</a>をダウンロードしてください。
+</p>
+
+<h3>重要な動作の変更点</h3>
+
+<p>過去に Android にアプリを公開したことがある場合は、アプリがプラットフォームの変更による影響を受ける場合があります。
+</p>
+
+<p>詳細については、<a href="behavior-changes.html">Behavior Changes</a> をご覧ください。</p>
+
+<h2 id="app-linking">アプリのリンク機能</h2>
+<p>このプレビューでは、アプリのリンク機能を強化することで Android のインテント システムが向上しました。この機能では、所有するウェブドメインにアプリを関連付けることができます。
+この関連付けに基づいて、プラットフォームが特定のウェブリンクの処理に使用するデフォルトのアプリを決めることができ、ユーザーにアプリを選択させる操作をスキップできます。この機能の実装方法については、
+<a href="{@docRoot}preview/features/app-linking.html">アプリのリンク機能</a>をご覧ください。
+
+
+
+<h2 id="backup">アプリの自動バックアップ</h2>
+<p>システムで、アプリの自動フルデータ バックアップと復元を実行できるようになりました。この動作は、M Preview を対象としたアプリでデフォルトで有効になっています。追加のコードは必要ありません。
+ユーザーが Google アカウントを削除すると、バックアップ データも削除されます。
+この機能の仕組みとファイル システムでバックアップ対象を設定する方法については、
+<a href="{@docRoot}preview/backup/index.html">アプリの自動バックアップ</a>をご覧ください。
+</p>
+
+<h2 id="authentication">認証</h2>
+<p>このプレビューでは、サポートされる端末での指紋スキャンを使用したユーザー認証や、端末のロック解除メカニズム(ロック画面のパスワードなど)を使って最後にユーザーが認証された時期の確認などを行える新しい API が提供されます。
+
+これらの API は、<a href="{@docRoot}training/articles/keystore.html">Android キーストローク システム</a>と共に使用します。
+</p>
+
+<h3 id="fingerprint-authentication">指紋認証</h3>
+
+<p>指紋スキャンでユーザーを認証するには、新しい
+{@code android.hardware.fingerprint.FingerprintManager} クラスのインスタンスを取得して、
+{@code FingerprintManager.authenticate()} メソッドを呼び出します。アプリは、指紋センサー付きの、互換性のある端末上で実行している必要があります。
+指紋認証フローのユーザー インターフェースをアプリに実装し、UI には標準の Android 指紋アイコンを使用する必要があります。Android 指紋アイコン({@code c_fp_40px.png})は<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">サンプルアプリ</a>に含まれています。指紋認証を使用するアプリを複数開発する場合は、それぞれのアプリで個別にユーザーの指紋を認証する必要があります。
+
+
+
+
+</p>
+
+<p>アプリでこの機能を使用するには、まずマニフェストに {@code USE_FINGERPRINT} パーミッションを追加する必要があります。
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>アプリでの指紋認証の実装については、
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">指紋ダイアログのサンプル</a>をご覧ください。
+</p>
+
+<p>この機能をテストする場合は、次の手順を使用します。</p>
+<ol>
+<li>Android SDK Tools Revision 24.3 をインストールします(まだインストールしていない場合)。</li>
+<li>
+<strong>[設定] > [セキュリティ] > [指紋]</strong> の登録手順に従い、エミュレータに新しい指紋を登録します。</li>
+<li>エミュレータを使って、次のコマンドで指紋のタッチ ベントをエミュレートします。
+同じコマンドを使って、ロック画面やアプリでの指紋のタッチイベントをエミュレートします。
+
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>Windows では、{@code telnet 127.0.0.1 <emulator-id>}、
+{@code finger touch <finger_id>} の順に実行する必要がある場合があります。
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">資格情報の確認</h3>
+<p>アプリでは、ユーザーがいつ、最後に端末のロックを解除したかに基づいて、ユーザーを認証できます。この機能によって、ユーザーがアプリ固有のパスワードを覚えたり、開発者が独自の認証ユーザー インターフェースを実装したりする必要性がなくなります。
+
+アプリでこの機能を使用する場合は、ユーザー認証用の公開鍵か秘密鍵を実装する必要があります。
+</p>
+
+<p>ユーザーが正常に認証された後、同じキーを再使用できるタイムアウト期間を設定するには、{@link javax.crypto.KeyGenerator} か
+{@link java.security.KeyPairGenerator} のセットアップ後に新しい
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()} メソッドを呼び出します。
+
+現在、この機能は対象暗号化操作で動作します。
+</p>
+
+<p>再認証ダイアログを過度に表示しないようにします。アプリでは、まず暗号オブジェクトを使用し、タイムアウトした場合は
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} メソッドを使用してユーザーをアプリ内で再認証するようにします。
+
+
+</p>
+
+<p>アプリでのこの機能の実装については、
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">資格情報の確認サンプル</a>をご覧ください。
+</p>
+
+<h2 id="direct-share">ダイレクト シェア</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>このプレビューでは、ユーザーが直感的にすばやく共有できるようにする API が提供されます。アプリで特定のアクティビティを起動する<em>ダイレクト シェアのターゲット</em>を定義すると、それらのダイレクト シェアのターゲットは <em>[共有]</em> メニューに表示されるようになります。
+
+この機能を使うと、他のアプリ内にある連絡先などのターゲットにコンテンツを共有できます。
+たとえば、ダイレクト シェアのターゲットによって他のソーシャル ネットワーク アプリのアクティビティが起動し、そのアプリ内の特定の友人やコミュニティに直接コンテンツを共有できるようになります。
+
+</p>
+
+<p>ダイレクト シェアのターゲットを有効にするには、まず
+{@code android.service.} を拡張するクラスを定義する必要があります。 <br>
+{@code chooser.ChooserTargetService} クラス。マニフェストで
+{@code ChooserTargetService} を宣言します。その宣言内で、
+{@code BIND_CHOOSER_TARGET_SERVICE} パーミッションと、
+{@code SERVICE_INTERFACE} アクションを使ったインテント フィルタを指定します。</p>
+<p>次の例は、マニフェストで {@code ChooserTargetService} を宣言する方法を示しています。
+</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>{@code ChooserTargetService} に公開するアクティビティごとに、 {@code "android.service.chooser.chooser_target_service"} という名前の
+{@code <meta-data>} 要素をアプリのマニフェストに追加します。
+
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">音声インタラクション</h2>
+<p>
+このプレビューでは、<a href="https://developers.google.com/voice-actions/" class="external-link">音声アクション</a>と共に使用することでアプリに対話形式の音声操作をビルドできる新しい音声インタラクション API が提供されます。
+
+
+{@code android.app.Activity.isVoiceInteraction()} メソッドを呼び出して、アクティビティが音声アクションへの応答として開始されたかどうかを確認します。
+音声アクションへの応答であった場合、アプリで
+{@code android.app.VoiceInteractor} クラスを使用してユーザーに音声の確認や、オプションのリストからの選択などを要求できます。
+音声アクションの実装の詳細については、
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">音声アクションの開発者サイト</a>をご覧ください。
+</p>
+
+<h2 id="assist">Assist API</h2>
+<p>
+このプレビューでは、アシスタントを介してユーザーがアプリを操作できる新しい方法が用意されています。この機能を使用するには、ユーザーが現在のコンテキストを使うようアシスタントを有効にする必要があります。
+有効にすると、<strong>ホーム</strong> ボタンを長押しすることで、すべてのアプリ内でアシスタントを呼び出すことができます。
+</p>
+<p>
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE} フラグを設定すると、アプリが現在のコンテキストをアシスタントと共有しないようにできます。新しい {@code android.app.Activity.AssistContent} クラスを使用すると、プラットフォームがアシスタントに渡す標準的な情報セットの他に、アプリで追加の情報を共有できます。
+
+</p>
+
+<p>アプリから追加のコンテキストをアシスタントに提供するには、次の手順を使用します。</p>
+
+<ol>
+<li>{@link android.app.Application.OnProvideAssistDataListener} インターフェースを実装します。</li>
+<li>
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()} を使用してこのリスナーを登録します。</li>
+<li>アクティビティ固有の文脈情報を提供するには、
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} コールバックと、任意で新しい
+{@code Activity.onProvideAssistContent()} コールバックをオーバーライドします。
+</ol>
+
+<h2 id="notifications">通知</h2>
+<p>このプレビューでは、通知に関して次のような API の変更点が追加されています。</p>
+<ul>
+ <li>新しい<em>アラームのみの</em> Do not disturb モードに相当する新しい {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} フィルタレベル。
+</li>
+ <li>ユーザーが予定したリマインダを他のイベント({@link android.app.Notification#CATEGORY_EVENT})やアラーム({@link android.app.Notification#CATEGORY_ALARM})から区別する際に使用される新しい{@code Notification.CATEGORY_REMINDER} カテゴリの値。
+
+
+</li>
+ <li>{@code Notification.Builder.setSmallIcon(Icon)} メソッドや {@code Notification.Builder.setLargeIcon(Icon)} メソッド経由で通知にアタッチできる新しい {@code android.graphics.drawable.Icon} クラス。
+
+</li>
+ <li>現在どの通知がアクティブなのかをアプリが検出できるようにする新しい {@code NotificationManager.getActiveNotifications()} メソッド。
+この機能を使用するアプリの実装については、<a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">アクティブな通知のサンプル</a>をご覧ください。
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Bluetooth スタイラスのサポート</h2>
+<p>このプレビューでは、Bluetooth スタイラスを使用したユーザー入力のサポートが強化されました。互換性のある Bluetooth スタイラスと電話やタブレットをペアリングして接続できます。
+接続されている間、タッチスクリーンからの位置情報とスタイラスからの筆圧やボタン情報を合わせることで、タッチスクリーン単独の場合よりも表現の幅が大きく広がります。
+
+新しい
+{@code View.onStylusButtonPressListener} コールバックと {@code GestureDetector.OnStylusButtonPressListener} コールバックをアクティビティに登録すると、スタイラスのボタンが押されたことをアプリがリッスンし、次のアクションを実行できるようになります。
+
+</p>
+
+<p>スタイラスのボタン操作を検出するには、{@link android.view.MotionEvent} メソッドと定数を使用します。
+</p>
+<ul>
+<li>ユーザーがスタイラスでアプリ画面のボタンをタップすると、
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} メソッドが
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS} を返します。</li>
+<li>M Preview を対象としたアプリでは、ユーザーがプライマリのスタイラス ボタンを押すと
+{@link android.view.MotionEvent#getButtonState() getButtonState()} メソッドが {@code MotionEvent.STYLUS_BUTTON_PRIMARY} を返します。
+
+スタイラスにセカンダリ ボタンがある場合は、ユーザーがそのボタンを押したときに同じメソッドで {@code MotionEvent.STYLUS_BUTTON_SECONDARY} が返されます。
+ユーザーが同時に両方のボタンを押した場合は、両方の値が OR で返されます({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY})
+
+</li>
+<li>
+以前のプラットフォーム バージョンを対象としたアプリでは、
+{@link android.view.MotionEvent#getButtonState() getButtonState()} メソッドは
+{@link android.view.MotionEvent#BUTTON_SECONDARY}(プライマリのスタイラス ボタンが押されたとき)、
+{@link android.view.MotionEvent#BUTTON_TERTIARY}(セカンダリのスタイラス ボタンが押されたとき)、または両方を返します。
+</li>
+</ul>
+
+<h2 id="ble-scanning">Bluetooth Low Energy のスキャンの改善</h2>
+<p>
+アプリで Bluetooth Low Energy スキャンを実行する場合は、新しい
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} メソッドを使って、設定された
+{@link android.bluetooth.le.ScanFilter} に一致する宣伝パケットが最初に見つかったときと、それが長期間見つからない場合に通知する目的でのみコールバックが必要であると指定できます。
+
+このスキャン アプローチは、以前のプラットフォーム バージョンで提供されていたものよりもはるかに効率的です。
+
+</p>
+
+<h2 id="hotspot">アクセス ポイント 2.0 リリース 1 のサポート</h2>
+<p>
+このプレビューでは、Nexus 6 と Nexus 9 端末のアクセス ポイント2.0 Release 1 仕様のサポートが追加されました。アクセス ポイント 2.0 の資格情報をアプリに提供するには、
+{@code setPlmn()} や {@code setRealm()} などの
+{@link android.net.wifi.WifiEnterpriseConfig} クラスの新しいメソッドを使用します。
+{@link android.net.wifi.WifiConfiguration} オブジェクトで、
+{@link android.net.wifi.WifiConfiguration#FQDN} フィールドと {@code providerFriendlyName} フィールドを設定できます。新しい {@code ScanResult.PasspointNetwork} プロパティは、検出されたネットワークがアクセス ポイント 2.0 のアクセス ポイントを表しているかどうかを示します。
+
+
+</p>
+
+<h2 id="4K-display">4K ディスプレイ モード</h2>
+<p>互換性のあるハードウェアで、ディスプレイの解像度を 4K レンダリングにアップグレードするようアプリから要求できるようになりました。
+現在の物理的解像度を照会するには、新しい
+{@code android.view.Display.Mode} API を使用します。UI が低い論理的解像度で描画されていて、より高い物理的解像度にアップスケールされた場合は、
+{@code Display.Mode.getPhysicalWidth()} メソッドが返す物理的解像度が {@link android.view.Display#getSize(android.graphics.Point) getSize()} で報告される論理的解像度と異なる場合があります。
+
+</p>
+
+<p>アプリ ウィンドウの
+{@code WindowManager.LayoutParams.preferredDisplayModeId} プロパティを設定することで、アプリの実行時に物理的解像度を変更するようシステムに要求できます。この機能は、4K ディスプレイの解像度に切り替えたい場合に便利です。
+4K ディスプレイ モード中、UI は引き続き元の解像度(1080p など)で表示され、4K にアップスケールされますが、
+{@link android.view.SurfaceView} オブジェクトではコンテンツをネイティブの解像度で表示する場合があります。
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">テーマ化可能な ColorStateLists</h2>
+<p>M Preview を実行する端末で、テーマの属性が
+{@link android.content.res.ColorStateList} でサポートされるようになりました。
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} メソッドと
+{@link android.content.res.Resources#getColor(int) getColor()} メソッドは廃止されました。これらの API を呼び出す場合は、代わりに新しい {@code Context.getColorStateList()} メソッドか
+{@code Context.getColor()} メソッドを呼び出します。
+これらのメソッドは、{@link android.support.v4.content.ContextCompat} の v4 appcompat ライブラリにもあります。
+</p>
+
+<h2 id="audio">オーディオ機能</h2>
+
+<p>このプレビューでは、次のように Android でのオーディオ処理が改善されました。 </p>
+<ul>
+ <li>新しい {@code android.media.midi} API を使った <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> プロトコルのサポート。
+これらの API を使用して MIDI イベントを送受信できます。
+</li>
+ <li>デジタル オーディオの録音を作成して、それぞれのオブジェクトを再生し、システムのデフォルトをオーバーライドするオーディオ ソースとシンク プロパティを構成するための新しい {@code android.media.AudioRecord.Builder} クラスと {@code android.media.AudioTrack.Builder} クラス
+
+。</li>
+ <li>オーディオと入力端末を関連付ける API フック。これは、ユーザーが Android TV に接続されているゲーム コントローラーやリモート コントロールから音声検索を開始できるアプリの場合に特に便利です。ユーザーが検索を開始すると、システムが新しい
+{@code android.app.Activity.onSearchRequested()} コールバックを呼び出します。
+
+ユーザーの入力端末に組み込みのマイクがあるかどうかを確認するには、そのコールバックから {@link android.view.InputDevice} オブジェクトを取得して、新しい
+{@code InputDevice.hasMic()} メソッドを呼び出します。
+</li>
+ <li>アタッチされたすべてのソースとシンク オーディオ端末の一覧を取得できる新しい {@code android.media.AudioDevicesManager} クラス。
+また、オーディオ端末の接続時と接続解除時にアプリで通知を受けたい場合は、
+{@code android.media.OnAudioDeviceConnectionListener} オブジェクトを指定することもできます。
+</li>
+</ul>
+
+<h2 id="video">ビデオ機能</h2>
+<p>このプレビューでは、ビデオ処理の API に次のような新機能が追加されました。</p>
+<ul>
+<li>アプリでオーディオ ストリームとビデオ ストリームを同調してレンダリングできる新しい {@code android.media.MediaSync}。
+オーディオ バッファはノンブロッキング方式で送信され、コールバック経由で返されます。
+ダイナミック再生レートもサポートしています。
+</li>
+<li>アプリで開かれたセッションが、リソース マネージャーによって再要求されたことを示す新しい {@code MediaDrm.EVENT_SESSION_RECLAIMED} イベント。
+アプリが DRM セッションを使用する場合は、必ずこのイベントを処理し、再要求されたセッションは使用しないようにします。
+
+</li>
+<li>リソース マネージャーがコーデックで使用されたメディア リソースを再要求したことを示す新しい {@code MediaCodec.CodecException.ERROR_RECLAIMED} エラーコード。
+この例外では、コーデックはターミナル状態に移動するため、解放する必要があります。
+
+</li>
+<li>同時に発生できるコーデック インスタンスの最大数のヒントを得られる新しい {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} インターフェース。
+
+</li>
+<li>高速または低速モーション再生におけるメディアの再生レートを設定する新しい {@code MediaPlayer.setPlaybackParams()} メソッド。
+ビデオと共にオーディオの再生を自動的に延ばしたり早めたりもします。
+</li>
+</ul>
+
+<h2 id="camera">カメラ機能</h2>
+<p>このプレビューでは、カメラのフラッシュやカメラによる画像の再処理にアクセスするための新しい API が用意されています。
+</p>
+
+<h3 id="flashlight">Flashlight API</h3>
+<p>カメラ端末にフラッシュ ユニットが付属している場合は、{@code CameraManager.setTorchMode()} メソッドを呼び出すことで、カメラ端末を開かずにフラッシュ ユニットのタッチモードのオン/オフを切り替えることができます。
+アプリには、フラッシュ ユニットやカメラ端末のフラッシュの独占所有権はありません。
+トーチモードは、カメラ端末が利用不可になったときや、トーチを付けている他のカメラリソースが利用不可になったときにオフになり、利用できなくなります。
+
+他のアプリでも {@code setTorchMode()} を呼び出してトーチモードをオフにできます。
+最後にトーチモードをオンにしたアプリが閉じられると、トーチモードはオフになります。
+</p>
+
+<p>
+{@code CameraManager.registerTorchCallback()} メソッドを呼び出すことで、トーチモードの状態に関する通知を受けるようコールバックを登録できます。コールバックを初めて登録したときに、現在検知されているすべてのフラッシュ ユニット付きのカメラ端末のトーチモードの状態が即座に呼び出されます。
+
+トーチモードが正常にオン/オフされると、
+{@code CameraManager.TorchCallback.onTorchModeChanged()} メソッドが呼び出されます。</p>
+
+<h3 id="reprocessing">Reprocessing API</h3>
+<p>{@link android.hardware.camera2 Camera2} API は、YUV とプライベートな不透明形式の画像の再処理をサポートするよう拡張されました。
+アプリは、再処理機能が利用可能かどうかを {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES} 経由で確認します。
+端末が再処理をサポートしている場合は、
+{@code CameraDevice.createReprocessableCaptureSession()} を呼び出して再処理可能なカメラ撮影セッションを作成し、入力バッファの再処理の要求を作成できます。
+
+</p>
+
+<p>入力バッファのフローをカメラの再処理入力に接続するには、{@code ImageWriter} クラスを使用します。
+空のバッファを取得するには、次のプログラミング モデルを使用します。</p>
+
+<ol>
+<li>{@code ImageWriter.dequeueInputImage()} メソッドを呼び出します。</li>
+<li>入力バッファにデータを入力します。</li>
+<li>{@code ImageWriter.queueInputImage()} メソッドを呼び出して、バッファをカメラに送ります。</li>
+</ol>
+
+<p>{@code ImageWriter} オブジェクトを
+{@code android.graphics.ImageFormat.PRIVATE} 画像と共に使用する場合、アプリから直接画像データにアクセスすることはできません。
+代わりに、{@code ImageWriter.queueInputImage()} メソッドをバッファコピーなしで呼び出して、{@code ImageFormat.PRIVATE} 画像を直接
+{@code ImageWriter} に渡します。
+</p>
+
+<p>{@code ImageReader} クラスで {@code android.graphics.ImageFormat.PRIVATE} 形式の画像ストリームがサポートされるようになりました。
+これにより、アプリが
+{@code ImageReader} 出力画像の循環的な画像のキューを維持でき、1 つ以上の画像を選択して、それらをカメラの再処理用に
+{@code ImageWriter} に送ることができます。</p>
+
+<h2 id="afw">Android for Work の機能</h2>
+<p>このプレビューには、次のような Android for Work 用の新しい API が含まれています。</p>
+<ul>
+ <li><strong>企業の専用端末の制御の強化:</strong>デバイス オーナーは次の設定を制御でき、企業の専用端末を管理しやすくなります。
+
+
+ <ul>
+ <li>
+{@code DevicePolicyManager.setKeyguardEnabledState()} メソッドを使ったキーガードの無効化と有効化。</li>
+ <li>
+{@code DevicePolicyManager.setStatusBarEnabledState()} メソッドを使ったステータスバー(クイック設定、通知、Google Now を起動するスワイプアップのジェスチャ)の無効化と有効化。
+</li>
+ <li>{@link android.os.UserManager} の定数 {@code DISALLOW_SAFE_BOOT} を使ったセーフブートの無効化と有効化。
+</li>
+ <li>
+{@link android.provider.Settings.Global} の定数 {@code STAY_ON_WHILE_PLUGGED_IN} を使った電源接続時の画面オフの回避。</li>
+ </ul>
+ </li>
+ <li><strong>デバイス オーナーによるアプリのサイレント インストールとアンインストール:</strong>デバイス オーナーでは、{@link android.content.pm.PackageInstaller} API を使って、Google Play for Work から独立してアプリケーションをサイレントにインストール、アンインストールできます。
+
+デバイス オーナー経由で、ユーザー操作なしでアプリを取得したりインストールしたりできる端末を提供できます。
+この機能は、Google アカウントのアクティベートなしでキオスクや同様の端末のワンタッチ プロビジョニングを有効にする際に便利です。
+</li>
+<li><strong>企業証明書のサイレント アクセス: </strong>ユーザーが証明書の選択を求められる前にアプリが
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()} を呼び出すと、プロファイルやデバイス オーナーが {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} メソッドを呼び出して要求元のアプリケーションにエイリアスをサイレントに提供できるようになりました。
+
+
+この機能によって、ユーザー操作なしでマネージド アプリが証明書にアクセスできるようになります。
+</li>
+<li><strong>システムアップデートの自動受信。</strong>
+{@code DevicePolicyManager.setSystemUpdatePolicy()} を使ってシステムアップデートのポリシーを設定することで、デバイス オーナーがキオスク端末などでシステムアップデートを自動的に受信できるようにしたり、ユーザーが操作しないようアップデートを最大 30 日間保留したりできます。
+
+さらに、管理者はアップデートを実行する時間枠を、キオスク端末が使用されていない時間帯などに設定できます。
+利用可能なシステムアップデートがある場合、システムは Work Policy Controller アプリにシステムアップデートのポリシーがあるかどうかを確認し、それに基づいて動作します。
+
+
+</li>
+<li>
+<strong>代理証明書のインストール:</strong>プロファイルやデバイス オーナーで、サードパーティ アプリが次の {@link android.app.admin.DevicePolicyManager} 証明書の管理 API を呼び出す権限を付与できるようになりました。
+
+
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>企業のファクトリー リセット制限:</strong>デバイス オーナーをプロビジョニングする際、
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} バンドルを設定して、ファクトリー リセット保護(FRP)をロック解除するようパラメータを構成できます。
+NFC プログラマー アプリでは、端末が FRP のロック解除するようリセットされ、端末がプロビジョニングされた後にこれらのパラメータを提供でき、事前に Google アカウントを設定しておく必要はありません。
+
+これらのパラメータを修正しない場合、FRP は続行し、事前にアクティブ化された Google の資格情報なしで端末がアクティベートされないようにします。
+
+
+<p>さらに、Google Play サービスでアプリの制限を設定することで、デバイス オーナーは FRP のロック解除用の別の Google アカウントを指定して、端末でアクティベートされたアカウントを置き換えることができます。
+</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>データ使用のトラッキング</strong>プロファイルやデバイス オーナーでは、新しい
+{@code android.app.usage.NetworkStatsManager} メソッドを使用して、<strong>[設定] > [データ]</strong> に表示されるデータ使用の統計を照会できます。
+プロファイル オーナーには、管理するプロファイルのデータを照会するパーミッションが自動的に付与され、デバイス オーナーは管理されたプライマリ ユーザーの使用データへのアクセス権が付与されます。
+
+</li>
+<li><strong>実行時パーミッションの管理:</strong>
+<p>プロファイルやデバイス オーナーは、
+{@code DevicePolicyManager.setPermissionPolicy()} を使用するすべてのアプリケーションのすべての実行時の要求に対するパーミッション ポリシーを設定でき、通常のとおりユーザーにパーミッションを付与するよう要求する、自動的に付与する、パーミッションをサイレントに拒否する、のいずれかを行うことができます。
+
+後者のポリシーが設定されている場合、ユーザーはプロファイルやデバイス オーナーによって選択された内容を <strong>[設定]</strong> にあるアプリのパーミッション画面で修正できません。
+
+</p></li>
+<li><strong>設定の VPN:</strong>VPN アプリは、<strong>[設定] > [その他] > [VPN]</strong> に表示されます。さらに、VPN の使用に関する通知は、その VPN の構成状況によるものになります。
+
+
+プロファイル オーナーの場合、通知は VPN が マネージド プロファイル、個人プロファイル、または両方のどれに構成されているかによって、それ固有のものになります。
+デバイス オーナーの場合、通知は VPN が端末全体に構成されているかどうかによって、それ固有のものになります。
+</li>
+<li><strong>ワーク ステータスの通知:</strong>マネージド プロファイルからのアプリのアクティビティがフォアグラウンドにある場合は、ステータスバーのブリーフケース アイコンが表示されます。
+さらに、端末がマネージド プロファイルのアプリのアクティビティに直接ロック解除されている場合、ユーザーがワーク プロファイル内にいることがトースト通知で表示されます。
+
+
+</li>
+</ul>
+
+<p class="note">
+ M Developer Preview のすべての API の変更点の詳細については、<a href="{@docRoot}preview/download.html">API Differences Report</a> をご覧ください。
+</p>
diff --git a/docs/html-intl/intl/ja/preview/behavior-changes.jd b/docs/html-intl/intl/ja/preview/behavior-changes.jd
new file mode 100644
index 0000000..a7950a1
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=動作の変更点
+page.keywords=プレビュー,sdk,compatibility
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本書の内容</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">実行時パーミッション</a></li>
+ <li><a href="#behavior-power">省電力の最適化 </a>
+ <ol>
+ <li><a href="#behavior-doze">Doze</a></li>
+ <li><a href="#behavior-app-standby">App Standby</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">追加可能なストレージ端末</a></li>
+ <li><a href="#behavior-apache-http-client">Apache HTTP Client の削除</a></li>
+ <li><a href="#behavior-audiomanager-Changes">AudioManager の変更点</a></li>
+ <li><a href="#behavior-test-selection">テキスト選択</a></li>
+ <li><a href="#behavior-keystore">Android キーストロークの変更点</a></li>
+ <li><a href="#behavior-network">Wi-Fi とネットワークの変更点</a></li>
+ <li><a href="#behavior-camera">カメラ サービスの変更点</a></li>
+ <li><a href="#behavior-art-runtime">ART ランタイム</a></li>
+ <li><a href="#behavior-apk-validation">APK の検証</a></li>
+ <li><a href="#behavior-afw">Android for Work の変更点</a></li>
+</ol>
+
+<h2>API の変更点</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API レベル 22 から M Preview»</a> </li>
+</ol>
+
+
+<h2>関連ドキュメント</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">M Developer Preview API の概要</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview には、新機能以外にもさまざまなシステムの変更点や API の動作の変更点が盛り込まれています。
+このドキュメントでは、アプリ開発において把握しておくべき主な変更点について説明します。
+</p>
+
+<p>過去に Android にアプリを公開したことがある場合は、アプリがこれらの変更による影響を受ける場合があることに注意してください。
+</p>
+
+<h2 id="behavior-runtime-permissions">実行時パーミッション</h1>
+<p>このプレビューでは、アプリのパーミッションを実行時にユーザーが直接管理できる新しいパーミッション モデルが採用されました。
+このモデルによって、ユーザーに対するパーミッションの可視性と制御性が向上し、アプリ開発者にとってはアプリのインストールや自動アップデート プロセスの効率が上がります。ユーザーはインストール済みアプリのパーミッションを個別に付与したり取り消したりできます。
+
+ </p>
+
+<p>M Preview を対象としたアプリでは、必ずパーミッションを実行時に確認、要求するようにします。
+アプリにパーミッションが付与されているかどうかを確認するには、新しい {@code Context.checkSelfPermission()} メソッドを呼び出します。
+パーミッションを要求するには、新しい
+{@code Activity.requestPermission()} メソッドを呼び出します。アプリが M を対象としていない場合でも、新しいパーミッション モデルでアプリをテストするようにしてください。
+</p>
+
+<p>アプリで新しいパーミッションをサポートする際の詳細については、Developer Preview ページの
+<a href="{@docRoot}preview/features/runtime-permissions.html">Permissions</a> をご覧ください。
+アプリへの影響を評価する際のヒントについては、<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Testing Guide</a> をご覧ください。
+</p>
+
+<h2 id="behavior-power">省電力の最適化 </h2>
+<p>このプレビューでは、アイドル中の端末やアプリに対する新しい省電力の最適化機能が採用されています。</p>
+
+<h3 id="behavior-doze">Doze</h3>
+<p>端末が電源に接続されておらず、画面が一定時間オフ状態の場合は <em>Doze</em> モードに入り、システムをスリープ状態に保ちます。
+このモードでは、端末は定期的に通常の操作を短時間再開することで、アプリを同期したり、システムが保留中の操作を行ったりすることができます。
+
+</p>
+
+<p>Doze 中は、アプリに次の制限が適用されます。</p>
+<ul>
+<li>アプリで優先度の高い Google Cloud Messaging の通知を受信する場合以外、ネットワーク アクセスは無効になります。
+</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Wake ロック</a> は無視されます。</li>
+<li>{@link android.app.AlarmManager} クラスを使ってスケジュールされたアラームは無効になりますが、{@link android.app.AlarmManager#setAlarmClock setAlarmClock()} メソッドと {@code AlarmManager.setAndAllowWhileIdle()} を使って設定したアラームは除きます。
+
+</li>
+<li>WiFi スキャンは実行されません。</li>
+<li>同期アダプタ と {@link android.app.job.JobScheduler} の同期とジョブは実行できません。
+</li>
+</ul>
+</p>
+<p>端末が Doze モードでなくなると、保留中のすべての同期とジョブが実行されます。</p>
+<p>この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>注</strong>:
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a> の次期リリースでは、高優先度のメッセージを指定できます。
+
+アプリが高優先度の GCM メッセージを受信する場合は、端末が Doze 中でも短時間のネットワーク アクセスが付与されます。
+
+</p>
+
+<p>アプリで Doze をテストする方法のヒントについては、
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</a> をご覧ください。
+ </p>
+
+<h3 id="behavior-app-standby">App Standby</h3>
+<p>このプレビューでは、アクティブに使用されていないアプリをシステムがアイドル状態であるとみなす場合があります。
+システムが次の信号を検出しない場合、一定時間の経過後にアプリはアイドル状態であるとみなされます。
+</p>
+
+<ul>
+<li>アプリがユーザーによって明示的に起動された。</li>
+<li>アプリのプロセスが現在フォアグラウンドにある(アクティビティかフォアグラウンド サービスとしてか、他のアクティビティかフォアグラウンド サービスによって使用されている)。
+</li>
+<li>アプリがロック画面や通知トレイに表示される通知を生成する。
+</li>
+<li>ユーザーが、アプリに最適化が適用されないよう <strong>[設定]</strong> で明示的に指定する。
+</li>
+</ul>
+
+<p>端末が電源に接続されていない場合、アイドル中のみなされたアプリのネットワーク アクセスは無効になり、同期とジョブは保留されます。
+端末が電源に接続されると、アプリのネットワーク アクセスは許可され、保留中のすべてのジョブと同期が実行されます。
+端末が長時間アイドル状態の場合、アイドル中のアプリは 1 日 1 回程度ネットワーク アクセスが許可されます。
+</p>
+
+<p>この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>注:</strong>
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a>(GCM)の次期リリースでは、高優先度のメッセージを指定できます。
+
+アプリが高優先度の GCM メッセージを受信する場合は、アプリがアイドル 中でも短時間のネットワーク アクセスが付与されます。
+
+</p>
+
+<p>アプリで App Standby をテストする方法のヒントについては、
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">Testing Guide</a> をご覧ください。
+ </p>
+
+<h2 id="behavior-adoptable-storage">追加可能なストレージ端末</h2>
+<p>
+このプレビューでは、SD カードなどの外部ストレージ端末を<em>追加</em>できます。外部ストレージ端末を追加すると、端末が内部ストレージのように動作するよう暗号化とフォーマットが行われます。
+この機能によって、アプリとアプリの個人データをストレージ端末間で移動できるようになります。
+アプリを移動する際、システムはマニフェストの
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> を遵守します。
+
+</p>
+
+<p>アプリが次の API やフィールドにアクセスする場合は、アプリが内部ストレージ端末と外部ストレージ端末間で移動する際に返されるファイルパスが動的に変化することに注意してください。ファイルパスの構築時は、これらの API を動的に呼び出すことを強くお勧めします。ハードコードされたファイル パスを使用したり、過去にビルドした完全修飾ファイルパスをそのまま使用したりしないでください。
+
+
+</p>
+
+<ul>
+<li>{@link android.content.Context} メソッド:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>{@link android.content.pm.ApplicationInfo} フィールド:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>Developer Preview のこの機能をデバッグするには、USB On-The-Go(OTG)ケーブルで Android 端末に接続された USB ドライブの追加を有効にして、次のコマンドを実行します。
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Apache HTTP Client の削除</h2>
+<p>このプレビューでは、Apache HTTP クライアントのサポートが削除されました。アプリでこのクライアントを使用していて、Android 2.3(API レベル 9)以上を対象としている場合は、代わりに {@link java.net.HttpURLConnection} クラスを使用します。
+
+この API は透過的データ圧縮と応答のキャッシュによってネットワーク使用を軽減し、電源の消費を最小化するため、効率性が向上します。
+Apache HTTP API を引き続き使用するには、まず {@code build.gradle} ファイルで次のコンパイル時の依存関係を宣言する必要があります。
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android は、OpenSSL から
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> ライブラリに移行しています。
+アプリで Android NDK を使用している場合は、{@code libcrypto.so} や {@code libssl.so} など、NDK API の一部でない暗号化ライブラリにリンクしないでください。
+これらのライブラリは パブリック API ではなく、リリースや端末に対する通知なしで変更されたり、中断したりする可能性があります。また、セキュリティ上の脆弱性を露呈する場合もあります。
+
+代わりに、ネイティブ コードを変更して JNI 経由で Java の暗号化 API を呼び出すか、希望の暗号化ライブラリに静的リンクします。
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">AudioManager の変更点</h2>
+<p>{@link android.media.AudioManager} クラスで音量を直接設定したり、特定のストリームをミュートにしたりする方法はサポートされなくなりました。
+{@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} メソッドは廃止されたため、代わりに
+{@code AudioManager.requestAudioFocus()} メソッドを呼び出す必要があります。同様に、
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} メソッドも廃止され、代わりに {@code AudioManager.adjustStreamVolume()} メソッドを呼び出して、値に {@code ADJUST_MUTE} か {@code ADJUST_UNMUTE} を渡します。
+
+</p>
+
+<h2 id="behavior-test-selection">テキスト選択</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>ユーザーがアプリ内でテキストを選択するとき、
+<em>切り取り</em>、<em>コピー</em>、<em>貼り付け</em>などのテキスト選択のアクションを
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">フローティング ツール バー</a>に表示できるようになりました。
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">個別のビューに対してコンテキスト アクション モードを有効にする</a>にあるように、コンテキスト アクションバーに関するユーザー操作の実装も同様です。
+
+</p>
+
+<p>テキスト選択にフローティング ツール バーを実装するには、既存のアプリに次の変更を加えます。
+</p>
+<ol>
+<li>{@link android.view.View} オブジェクトか {@link android.app.Activity} オブジェクトで、{@link android.view.ActionMode} の呼び出しを
+{@code startActionMode(Callback)} から {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)} に変更します。
+</li>
+<li>既存の {@code ActionMode.Callback} の実装を、{@code ActionMode.Callback2} に拡張します。
+</li>
+<li>{@code Callback2.onGetContentRect()} メソッドをオーバーライドして、ビューのコンテンツの {@link android.graphics.Rect} オブジェクト)テキスト選択の四角形など)の座標を指定します。
+</li>
+<li>四角形の位置が有効でなくなり、無効な要素がこれのみである場合は、{@code ActionMode.invalidateContentRect()} メソッドを呼び出します。
+</li>
+</ol>
+
+<p><a href="{@docRoot}tools/support-library/index.html">
+Android Support Library</a> revision 22.2 を使用している場合、フローティング ツール バーに下方互換性はなく、デフォルトで appcompat が代わりに {@link android.view.ActionMode} オブジェクトを制御することに注意してください。
+
+これにより、フローティング ツール バーは表示されなくなります。
+{@link android.support.v7.app.AppCompatActivity} で
+{@link android.view.ActionMode} がサポートされるようにするには、
+{@code android.support.v7.app.AppCompatActivity.getDelegate()} を呼び出して、返された
+{@link android.support.v7.app.AppCompatDelegate} オブジェクトで
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} を呼び出し、 入力パラメータを {@code false} に設定します。
+この呼び出して、{@link android.view.ActionMode} オブジェクトの制御がフレームワークに戻ります。
+M Preview を実行する端末ではフレームワークによる
+{@link android.support.v7.app.ActionBar} やフローティング ツール バー モードのサポートが可能ですが、M Preview 以前の端末では
+{@link android.support.v7.app.ActionBar} モードのみがサポートされます。</p>
+
+<h2 id="behavior-keystore">Android キーストロークの変更点</h2>
+<p>このプレビューでは、
+<a href="{@docRoot}training/articles/keystore.html">Android Keystore プロバイダ</a>による DSA のサポートがなくなります。
+ECDSA は引き続きサポートされます。</p>
+
+<p>停止時に暗号化を必要としないキーが、ロック画面の(ユーザーや端末の管理者などによる)無効時やリセット時に削除されなくなりました。
+停止時に暗号化を必要とするキーは、これらのイベント時に削除されます。
+</p>
+
+<h2 id="behavior-network">Wi-Fi とネットワークの変更点</h2>
+
+<p>このプレビューでは、Wi-Fi API とネットワーク API の動作に次のような変更点が追加されました。</p>
+<ul>
+<li>オブジェクトの作成者である場合のみ、アプリで{@link android.net.wifi.WifiConfiguration} オブジェクトの状態を変更できます。
+ユーザーや他のアプリによって作成された
+{@link android.net.wifi.WifiConfiguration} オブジェクトは変更、削除できません。
+</li>
+<li>
+以前は、
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} で
+{@code disableAllOthers=true} 設定を使ってアプリから端末を特定の Wi-Fi ネットワークに接続させた場合、端末はセルラー データなどの他のネットワークから切断されていました。
+このプレビューでは、端末が他のネットワークから切断されないようになりました。アプリの {@code targetSdkVersion} が {@code “20”} 以下の場合は、選択した Wi-Fi ネットワークに固定されます。
+
+アプリの {@code targetSdkVersion} が {@code “21”} 以上の場合は、マルチネットワーク API(
+{@link android.net.Network#openConnection(java.net.URL) openConnection()}メソッド、
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()}メソッド、新しい
+{@code ConnectivityManager.bindProcessToNetwork()} メソッドなど)を使用してネットワーク トラフィックが選択したネットワークに送られるようにします。
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">カメラ サービスの変更点</h2>
+<p>このプレビューでは、カメラ サービスの共有リソースへのアクセスモデルが、以前の "先着順" モデルから、"優先度順" に変更されました。
+
+この動作の変更には、次のようなものがあります。</p>
+<ul>
+<li>カメラ端末を開いて構成するなど、カメラのサブシステム リソースへのアクセスは、クライアント アプリケーション プロセスの "優先度" に基づいて与えられます。
+通常、ユーザーに表示されているアクティビティやフォアグラウンドにあるアクティビティのあるアプリケーション プロセスの優先度が最も高くなり、カメラ リソースの取得や使用の信頼性が高まります。
+
+</li>
+<li>優先度の低いアプリでアクティブなカメラ クライアントは、より優先度の高いアプリケーションがカメラを使おうとした際に使用が中断される場合があります。
+廃止された {@link android.hardware.Camera} API では、使用が中断されたクライアントに
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} が呼び出されます。
+
+{@link android.hardware.camera2 Camera2} API では、使用が中断されたクライアントに
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()} が呼び出されます。
+</li>
+<li>適切なカメラ ハードウェア付きの端末では、別のアプリケーション プロセスを独立して開き、別のカメラ端末を同時に使用できます。
+ただし、同時アクセスによってパフォーマンスや開いているカメラ端末の性能が著しく低下するマルチプロセスの使用が検出可能になり、カメラ サービスでは許可されなくなりました。
+
+この変更によって、同じカメラ端末にアクセスしようとしているアプリが他になくても、優先度の低いクライアントによる使用が中断される場合があります。
+
+
+</li>
+<li>
+現在のユーザーを変更すると、アプリ内で前のユーザー アカウントで所有していたアクティブなカメラ クライアントが中断させられることになります。
+カメラへのアクセスは、現在の端末ユーザーが所有するユーザー プロファイルのみに制限されます。つまり、ユーザーが別のアカウントに切り替えた場合、"ゲスト" アカウントはカメラのサブシステムを使用するプロセスを実行したまま去ることはできません。
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">ART ランタイム</h2>
+<p>ART ランタイムで、
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} メソッドに対するアクセスルールを正常に実装できるようになりました。この変更によって、以前のバージョンで Dalvik がアクセス ルールを正しく確認できなかった問題が解決しました。アプリで
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} メソッドを使用していて、アクセス チェックをオーバーライドしたい場合は、 {@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} メソッドを使って入力パラメータを {@code true} に設定します。
+
+
+
+
+アプリで
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat ライブラリ</a>や
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview ライブラリ</a>を使用する場合は、これらのライブラリの最新バージョンを使用するようアプリをアップデートする必要があります。
+アップデートしない場合は、XML から参照するカスタム クラスがアップデートされていて、クラス コンストラクタがアクセス可能であることを確認しておく必要があります。
+</p>
+
+<p>このプレビューでは、動的リンクの動作がアップデートされました。動的リンクでは、ライブラリの {@code soname} とそのパス(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+public bug 6670</a>)の違いを認識でき、{@code soname} が実装されています。
+
+
+以前動作していたアプリで間違った {@code DT_NEEDED} エントリを持つもの(ビルドマシンのファイル システムの絶対パスなど)は、読み込み時に失敗する場合があります。
+</p>
+
+<p>{@code dlopen(3) RTLD_LOCAL} フラグは正常に実装されました。
+{@code RTLD_LOCAL} はデフォルトのため、
+{@code RTLD_LOCAL} を明示的に使用しない {@code dlopen(3)} への呼び出しは影響を受けます(アプリで明示的に {@code RTLD_GLOBAL} を使用している場合を除く)。
+{@code RTLD_LOCAL} では、後に
+{@code dlopen(3)} への呼び出しで読み込まれたライブラリで記号は使用できません({@code DT_NEEDED} エントリによって参照された場合とは逆)。</p>
+</p>
+
+<h2 id="behavior-apk-validation">APK の検証</h2>
+<p>プラットフォームでより厳しい APK の検証が行われるようになりました。APK がマニフェスト ファイルで宣言されているにもかかわらず、APK 自体に存在しない場合、その APK は破損しているとみなされます。
+コンテンツが一部でも削除された場合は、APK の再署名が必要になります。
+</p>
+
+<h2 id="behavior-afw">Android for Work の変更点</h2>
+<p>このプレビューには、次のような Android for Work に関する動作の変更点が含まれています。</p>
+<ul>
+<li><strong>個人のコンテキストでの仕事用の連絡先</strong>ユーザーが過去の通話履歴を表示したときに、Google Dialer
+Call Log に仕事用の連絡先が表示されるようになりました。{@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} を {@code true} に設定すると、Google Dialer Call Log に仕事用プロファイルの連絡先は表示されなくなります。
+
+{@code DevicePolicyManager.setBluetoothContactSharingDisabled()} を {@code false} に設定した場合のみ、Bluetooth 経由で端末に仕事用の連絡先と個人用の連絡先を表示できます。
+
+デフォルトでは、{@code true} に設定されています。
+
+</li>
+<li><strong>WiFi 設定の削除:</strong>プロファイル オーナーによって追加された WiFi 設定(@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()} メソッドへの呼び出しなどを介して)は、その仕事用プロファイルが削除されると同時に削除されます。
+
+</li>
+<li><strong>WiFi 設定のロック:</strong>アクティブなデバイス オーナーによって作成された WiFi 設定は、ユーザーが修正したり削除したりできなくなりました。
+ユーザーに {@link android.os.UserManager} 定数
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} が設定されていない限り、ユーザー自身の WiFi 設定を作成、修正することはできます。
+</li>
+<li><strong>Google アカウントの追加経由での Work Policy Controller のダウンロード:</strong>Work Policy Controller(WPC)アプリ経由で管理する必要のある Google アカウントがマネージド コンテキスト外で端末に追加されると、アカウントの追加フローでユーザーに適切な WPC をインストールするよう要求します。この動作は、初期の端末のセットアップ ウィザードでの
+<strong>[設定]> [アカウント]</strong> で追加されるアカウントにも適用されます。
+
+
+</li>
+<li><strong>特定の DevicePolicyManager API の動作の変更点: </strong>
+{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} メソッドの呼び出しは、呼び出し元のユーザーのカメラにのみ影響を与えます。マネージド プロファイルから呼び出した場合は、プライマリ ユーザーで実行しているカメラ アプリに影響はありません。
+
+さらに、
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} メソッドは、デバイス オーナーに加えてプロファイル オーナーでも利用可能になりました。
+プロファイル オーナーは、これらのキーガード制限を設定できます:
+
+<ul>
+<li>プロファイルの親ユーザーのキーガード設定に影響を与える {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} と {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}。
+
+</li>
+<li>マネージド プロファイルのアプリケーションで生成された通知のみに影響を与える {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}。
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..f582756
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=パーミッション
+page.tags=previewresources, androidm
+page.keywords=パーミッション,実行時,プレビュー
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>クイックビュー</h2>
+ <ul>
+ <li>アプリのターゲットが M Preview SDK の場合、インストール時ではなく実行時に、パーミッションを付与するようユーザーに求めます。
+</li>
+ <li>ユーザーはいつでもアプリの [設定] 画面からパーミッションを取り消すことができます。
+</li>
+ <li>アプリは実行時に毎回、必要なパーミッションがあることを確認する必要があります。
+</li>
+ </ul>
+
+ <h2>本書の内容</h2>
+ <ol>
+ <li><a href="#overview">概要</a></li>
+ <li><a href="#coding">実行時のパーミッションのコード</a></li>
+ <li><a href="#testing">実行時のパーミッションをテストする</a></li>
+ <li><a href="#best-practices">ベスト プラクティス</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ M Developer Preview では、アプリをインストールしてアップグレードするユーザーのプロセスを効率化する新しいアプリのパーミッション モデルが導入されました。
+M Preview で実行しているアプリで新しいパーミッション モデルがサポートされている場合、ユーザーはアプリをインストールまたはアップグレードするときにパーミッションを付与する必要はありません。その代わりに、アプリは必要になるとパーミッションを要求し、パーミッションを確認するよう求めるダイアログが表示されます。
+
+
+
+
+</p>
+
+<p>
+ アプリで新しいパーミッション モデルがサポートされている場合、以前のバージョンの Android を実行している端末で、以前のパーミッション モデルを使ってインストールして実行することもできます。
+
+
+</p>
+
+<h2 id="overview">
+ 概要
+</h2>
+
+<p>
+ M Developer Preview とともに、プラットフォームでは新しいアプリのパーミッション モデルが導入されました。
+この新しいモデルの主要なコンポーネントの概要を次に示します。
+</p>
+
+<ul>
+ <li>
+ <strong>パーミッションを宣言する:</strong> アプリは、以前の Android プラットフォームと同様に、マニフェストで必要なすべてのパーミッションを宣言します。
+
+ </li>
+
+ <li>
+ <strong>パーミッション グループ:</strong> パーミッションは、その機能に基づいて<em>パーミッション グループ</em>に分けられます。
+たとえば、<code>CONTACTS</code> パーミッション グループにはユーザーの連絡先とプロフィール情報を読み書きするパーミッションが含まれます。
+
+
+ </li>
+
+ <li>
+ <p><strong>インストール時に付与される制限付きのパーミッション:</strong> ユーザーがアプリをインストールまたはアップデートするとき、{@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当する、アプリが要求するすべてのパーミッションがアプリに付与されます。
+
+
+ たとえば、目覚まし時計とインターネットのパーミッションは {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} に該当するため、インストール時に自動的にそれらのパーミッションが付与されます。
+
+ </p>
+
+ <p>システムは、<a href="#system-apps">システムアプリと署名のパーミッション</a>に記載のとおり、アプリの署名とシステムのパーミッションも付与することがあります。
+
+ユーザーは、インストール時にパーミッションを付与するように促すメッセージは表示<em>されません</em>。
+</p>
+ </li>
+
+ <li>
+ <strong>実行時にユーザーがパーミッションを付与する:</strong> アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。その後、アプリのコールバック関数を呼び出して、パーミッションが付与されているかどうかを知らせます。
+
+ユーザーがパーミッションを付与する場合、アプリ マニフェストで宣言されたパーミッションの機能領域にあるすべてのパーミッションがアプリに付与されます。
+
+
+ </li>
+
+</ul>
+
+<p>
+ このパーミッション モデルにより、パーミッションを要求する機能に対するアプリの動作方法が変わります。
+このモデルに合わせるために、従う必要のある開発プラクティスの概要を次に示します。
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>常にパーミッションを確認する:</strong> アプリがパーミッションを必要とするアクションを実行する必要があるとき、まずパーミッションが既にあるかどうかを確認する必要があります。
+
+パーミッションがない場合、そのパーミッションを付与するよう要求します。
+
+ </li>
+
+ <li>
+ <strong>パーミッションの不足をスムーズに処理する:</strong> アプリに適切なパーミッションが付与されていない場合、エラーが完全に処理される必要があります。
+
+ たとえば、追加機能に対してのみパーミッションが必要な場合、アプリはその機能を無効にできます。
+アプリが機能するためにパーミッションが必須である場合、アプリはすべての機能を無効にしてパーミッションを付与する必要があることをユーザーに知らせることがあります。
+
+
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>図 1.</strong>アプリの [設定] のパーミッション画面。
+ </p>
+ </div>
+
+ <li>
+ <strong>パーミッションは取り消し可能:</strong> ユーザーはいつでもアプリのパーミッションを取り消すことができます。
+アプリのパーミッションをオフにすると、アプリに通知<em>されません</em>。
+アプリは制限されたアクションを実行する前に、必要なパーミッションがあることを確認する必要があります。
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>注:</strong> アプリのターゲットが M Developer Preview の場合、新しいパーミッション モデルを使う<em>必要があります</em>。
+
+</p>
+
+<p>
+ M Developer Preview のローンチ時点では、すべての Google アプリで新しいパーミッション モデルが完全に実装されているわけではありません。
+Google はこれらのアプリを M Developer Preview 中にアップデートして、パーミッションの切り替え設定を完全に実装します。
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong> アプリに独自の API サーフェスがある場合、まず呼び出し側にそのデータへのアクセスに必要なパーミッションがあることを確認しないままパーミッションをプロキシしないでください。
+
+
+</p>
+
+<h3 id="system-apps">
+ システムアプリと署名のパーミッション
+</h3>
+
+<p>
+ 本来、ユーザーがアプリをインストールするとき、システムはアプリに
+ {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL} のみを付与します。ただし、特定の環境では、アプリにより多くのパーミッションが付与されます。
+
+</p>
+
+<ul>
+ <li>アプリがシステム イメージの一部である場合、そのマニフェストにリストされているすべてのパーミッションが自動的に付与されます。
+
+ </li>
+
+ <li>アプリが {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} に該当するマニフェストでパーミッションを要求し、アプリがこれらのパーミッションを宣言したアプリと同じ証明書で署名される場合、要求しているアプリに対してこれらのパーミッションがインストール時に付与されます。
+
+
+
+ </li>
+</ul>
+
+<p>
+
+
+どちらの場合でも、ユーザーはシステムの [<strong>設定</strong>] 画面に移動して [<strong>アプリ</strong>] > <i>[app_name]</i> > [<strong>パーミッション</strong>] を選ぶと、いつでもパーミッションを取り消すことができます。アプリは実行時にパーミッションを継続して確認し、必要に応じて要求する必要があります。
+
+
+</p>
+
+<h3 id="compatibility">
+ 上方互換と下方互換
+</h3>
+
+<p>
+ アプリのターゲットが M Developer Preview 以外の場合、M Preview 端末でも以前のパーミッション モデルを引き続き使います。
+ユーザーがアプリをインストールするとき、ユーザーはアプリのマニフェストでリストされているすべてのパーミッションを付与するように要求されます。
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong> M Developer Preview を実行している端末で、ユーザーはアプリの [設定] 画面から従来のアプリを含むすべてのアプリのパーミッションをオフにできます。
+
+従来のアプリに対してパーミッションをオフにすると、適切な機能がサイレント状態で無効になります。
+アプリがそのパーミッションを必要とする操作を実行しようとするとき、その操作によって必ずしも例外が発生するとは限りません。
+
+代わりに、空のデータセットを返す、エラーを示す、または予期しない動作を返すことがあります。
+たとえば、パーミッションなしでカレンダーを照会すると、メソッドは空のデータセットを返します。
+
+</p>
+
+<p>
+ M Preview を実行していない端末で新しいパーミッション モデルを使ってアプリをインストールする場合、他のすべてのアプリと同様に扱われ、インストール時に、すべての宣言されたパーミッションを付与するようユーザーに求めます。
+
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong> Preview リリースの場合、M Preview SDK に SDK の最小バージョンを設定して Preview SDK でコンパイルする必要があります。
+つまり、Developer Preview 中は従来のプラットフォームでそのようなアプリをテストできません。
+
+
+</p>
+
+<h3 id="perms-vs-intents">パーミッションとインテント</h3>
+
+<p>
+ 多くの場合、アプリがタスクを実行するには 2 つの方法から選択できます。
+アプリ自体が操作を実行するパーミッションを要求できます。
+アプリでインテントを使うようにして、別のアプリがそのタスクを実行するようにすることもできます。
+
+</p>
+
+<p>
+ たとえば、端末のカメラで写真を撮る機能がアプリに必要だとします。
+アプリは <code>android.permission.CAMERA</code> パーミッションをリクエストでき、それによりアプリが直接カメラにアクセスできるようになります。
+
+そのとき、アプリはカメラの API を使ってカメラを制御し、写真を撮ります。
+このアプローチにより、アプリが写真のプロセスを完全に制御し、カメラの UI をアプリに組み込むことができます。
+
+
+</p>
+
+<p>
+ ただし、そのような制御が不要な場合は、{@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} インテントを使うだけで画像を要求できます。
+インテントを開始すると、カメラアプリ(デフォルトのカメラアプリがない場合)を選んでアプリで写真を撮るよう求めるメッセージが表示されます。
+
+カメラアプリはアプリの {@link
+ android.app.Activity#onActivityResult onActivityResult()} メソッドに写真を返します。
+</p>
+
+<p>
+ 同様に、ユーザーの連絡先にアクセスするなどして電話をかける必要がある場合、適切なインテントを作成するか、パーミッションを要求して適切なオブジェクトに直接アクセスできます。
+
+各アプローチにはメリットとデメリットがあります。
+
+</p>
+
+<p>
+ パーミッションを使う場合:
+</p>
+
+<ul>
+ <li>操作を実行するとき、アプリによってユーザーの操作感が完全に制御されます。
+ただし、そのような幅広い制御により、適切な UI を設計する必要があるため、タスクが複雑化します。
+
+ </li>
+
+ <li>操作を初めて実行するときに、ユーザーに一度だけパーミッションの付与を求めるメッセージが表示されます。
+その後、アプリはユーザーからの介入は必要とせずに操作を実行できます。
+ただし、ユーザーがパーミッションを付与しない(または後でパーミッションを取り消す)場合、アプリは操作を一切実行できなくなります。
+
+
+ </li>
+</ul>
+
+<p>
+ インテントを使う場合:
+</p>
+
+<ul>
+ <li>操作用に UI を設計する必要はありません。インテントを処理するアプリでは UI が提供されますが、これはユーザーの操作感を制御できないことを意味します。
+
+ユーザーはこれまでに見たことのないアプリと相互操作することになります。
+
+ </li>
+
+ <li>操作に対してデフォルトのアプリを持たないユーザーの場合、ユーザーにアプリの選択を求めるメッセージが表示されます。ユーザーがデフォルトのハンドラを指定しない場合、操作のたびに別のダイアログで指定する必要があることがあります。
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">実行時のパーミッションのコード</h2>
+
+<p>
+ アプリのターゲットが新しい M Developer Preview の場合、新しいパーミッション モデルを使う必要があります。
+つまり、マニフェストで必要なパーミッションを宣言する他に、実行時にパーミッションがあることを確認し、まだパーミッションがない場合にはパーミッションを要求します。
+
+
+
+</p>
+
+<h3 id="enabling">
+ 新しいパーミッション モデルを有効にする
+</h3>
+
+<p>
+ 新しい M Developer Preview パーミッション モデルを有効にするには、アプリの <code>targetSdkVersion</code> 属性を <code>"MNC"</code> に、<code>compileSdkVersion</code> を <code>"android-MNC"</code> に設定します。
+
+このように設定することで、新しいパーミッション機能すべてが有効になります。
+
+</p>
+
+<p>
+ Preview リリースの場合、<code>minSdkVersion</code> を <code>"MNC"</code> に設定して Preview SDK でコンパイルする必要があります。
+
+</p>
+
+<h3 id="m-only-perm">
+ M Preview のみに対するパーミッションの設計
+</h3>
+
+<p>
+ アプリ マニフェストで新しい <code><uses-permission-sdk-m></code> 要素を使って、M Developer Preview のみで必要なパーミッションを表示できます。
+このようにしてパーミッションを宣言すると、アプリを以前の端末にインストールする場合はユーザーにメッセージが表示されないか、アプリにパーミッションが付与されません。<code><uses-permission-sdk-m></code> 要素を使うと、新しいパーミッションを追加してインストールをアップデートするときにパーミッションの付与を強制せずにアプリのバージョンがアップデートされます。
+
+
+
+
+
+
+</p>
+
+<p>
+ M Developer Preview を使ってアプリが端末で実行されている場合、<code><uses-permission-sdk-m></code> は <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> と同じように動作します。
+
+
+ アプリをインストールするとき、パーミッションの付与を求めるメッセージは表示されず、アプリは必要なときにパーミッションを要求します。
+
+</p>
+
+<h3 id="prompting">
+ パーミッションについてのダイアログを表示する
+</h3>
+
+<p>
+ アプリで新しい M Developer Preview パーミッション モデルが使われている場合、M Preview を実行している端末でアプリを初めて起動するとき、すべての権限を付与する必要はありません。
+
+その代わりに、アプリは必要なときにパーミッションを要求します。
+アプリがパーミッションを要求すると、ユーザーにダイアログが表示されます。
+
+</p>
+
+<p>
+ SDK 22 以降がインストールされた端末でアプリを実行する場合、アプリでは以前のパーミッション モデルが使われます。
+ユーザーがアプリをインストールすると、アプリがそのマニフェストで要求するすべてのパーミッションの付与を求めるメッセージが表示されます。ただし、<code><uses-permission-sdk-m></code> というラベルの付いたパーミッションは例外です。
+
+
+</p>
+
+<h4 id="check-platform">アプリが実行されているプラットフォームを確認する</h4>
+
+<p>
+ このパーミッション モデルは、M Developer Preview を実行している端末でのみサポートされます。
+これらのメソッドのいずれかを呼び出す前に、アプリは {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME} の値を確認してどのプラットフォーム上で実行されているのかを確認する必要があります。
+
+端末で M Developer Preview が実行されている場合、{@link android.os.Build.VERSION#CODENAME CODENAME} は <code>"MNC"</code> です。
+
+</p>
+
+<h4 id="check-for-permission">アプリに必要なパーミッションがあるかどうかを確認する</h4>
+
+<p>ユーザーがパーミッションを要求する動作を行うと、アプリは現在この操作を実行するためのパーミッションがあるかどうかを確認します。
+
+
+確認するために、アプリは <code>Context.checkSelfPermission(<i>permission_name</i>)</code> を呼び出します。ユーザーが既にパーミッションを付与していることをアプリが認識している場合でも、ユーザーはいつでもアプリのパーミッションを取り消すことができるため、この確認が行われます。
+
+
+たとえば、ユーザーがアプリを使って写真を撮る場合、アプリは <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code> を呼び出します。
+
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>表 1.</strong>パーミッションとパーミッション グループ。</p>
+<table>
+ <tr>
+ <th scope="col">パーミッション グループ</th>
+ <th scope="col">パーミッション</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">必要に応じてパーミッションを要求する</h4>
+
+<p>アプリに必要なパーミッションがない場合、アプリは <code>Activity.requestPermissions(String[], int)</code> メソッドを呼び出して適切なパーミッションを要求します。
+
+アプリは必要なパーミッションと整数の「要求コード」を渡します。
+
+ このメソッドは非同期に機能します。このメソッドはすぐに返され、ユーザーがダイアログ ボックスに応答した後、システムはその結果と一緒にアプリのコールバック メソッドを呼び出し、アプリが <code>requestPermissions()</code> に渡すのと同じ「要求コード」を渡します。
+
+
+</p>
+
+ <p>次のコードは、ユーザーの連絡先を読み込むパーミッションがアプリにあることを確認し、必要に応じてパーミッションを要求します。
+</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">パーミッションの要求への応答を処理する</h4>
+
+<p>
+ アプリがパーミッションを要求すると、システムによってダイアログ ボックスが表示されます。
+ユーザーが応答すると、システムはアプリの <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> を呼び出し、ユーザーの応答を渡します。
+
+アプリはそのメソッドをオーバーライドする必要があります。コールバックには開発者が <code>requestPermissions()</code> に渡したのと同じ要求コードが渡されます。
+
+たとえばアプリが <code>READ_CONTACTS</code> アクセスを要求する場合、次のコールバック メソッドが含まれる可能性があります。
+
+
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>ユーザーがパーミッションを付与すると、システムは、機能領域のアプリ マニフェストがリストするすべてのパーミッションを付与します。
+ユーザーが要求を拒否する場合は、適切なアクションを取ってください。
+たとえば、このパーミッションに応じて、すべてのメニュー アクションを無効にできます。
+
+ </li>
+</p>
+
+<p>
+ ユーザーにパーミッションの付与を確認するとき、ユーザーにそのパーミッションについて再度確認しないようにするオプションがあります。
+この場合、アプリが <code>requestPermissions()</code> を使ってパーミッションを確認すると、システムはその要求をすぐに拒否します。
+
+この場合、システムはユーザーが要求を再度明示的に拒否する場合と同様に <code>onRequestPermissionsResult()</code> を呼び出します。
+
+このため、アプリではユーザーとの直接的なやり取りが発生することが想定されません。
+
+</p>
+
+<h2 id="testing">実行時のパーミッションをテストする</h2>
+
+
+<p>
+ アプリのターゲットが M Developer Preview の場合、パーミッションが正しく処理されることをテストする必要があります。
+アプリ起動時に特定のパーミッションがアプリにあることは想定できません。
+アプリが初めて起動されるとき、パーミッションがない可能性が高く、ユーザーはいつでもパーミッションを取り消すまたは復元できます。
+
+
+</p>
+
+<p>
+ アプリがすべてのパーミッションの状況下で確実に正しく動作することをテストしてください。
+M Preview SDK とともに、新しい <a href="{@docRoot}tools/help/adb.html">Android デバッグ ブリッジ(adb)</a>コマンドが導入され、試す必要のあるあらゆるパーミッション設定でアプリをテストできます。
+
+
+
+</p>
+
+<h3>
+ 新しい adb コマンドとオプション
+</h3>
+
+<p>
+ M Preview SDK Platform-tools では、アプリがパーミッションをどう処理するかをテストするための、いくつかの新しいコマンドが導入されました
+
+</p>
+
+<h4>
+ パーミッション付きでインストールする
+</h4>
+
+<p>
+ <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a> コマンドの新しい <code>-g</code> オプションを使ってアプリをインストールし、そのマニフェストにリストされるすべてのパーミッションを付与できます。
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ パーミッションの付与と取り消し
+</h4>
+
+<p>
+ 新しい ADB <a href="{@docRoot}tools/help/adb.html#pm">Package Manager(pm)</a>コマンドを使って、インストールされているアプリにパーミッションを付与したり取り消したりできます。この機能は自動化されたテストに役立ちます。
+
+
+</p>
+
+<p>
+ パーミッションを付与するには、Package Manager の <code>grant</code> コマンドを使います。
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ たとえば、com.example.myapp パッケージ パーミッションを付与してオーディオを録音するには、このコマンドを使います。
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ パーミッションを取り消すには、Package Manager の <code>revoke</code> コマンドを使います。
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">ベスト プラクティス</h2>
+
+<p>
+ 新しいパーミッション モデルにより、ユーザーはよりスムーズな操作感を得られ、アプリを簡単にインストールできるようになり、アプリが実行している内容に満足します。
+
+新しいモデルを最大限に活用するために、次のベスト プラクティスをお勧めします。
+
+</p>
+
+
+<h3 id="bp-what-you-need">必要なパーミッションのみを要求する</h3>
+
+<p>
+ パーミッションを要求するたびに、ユーザーに決定するよう強制します。
+ ユーザーが要求を却下すると、アプリの機能が低下します。
+ これらの要求回数は最小限にしてください。
+</p>
+
+<p>
+ たとえば、アプリがパーミッションを要求する代わりに、<a href="{@docRoot}guide/components/intents-filters.html">インテント</a>を使って必要な機能を取得できる場合がよくあります。
+
+アプリが携帯電話のカメラで写真を撮る必要がある場合、そのアプリでは {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE} インテントを使用できます。
+アプリがインテントを実行すると、写真を撮るためのインストール済みのカメラアプリを選ぶようユーザーに促します。
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ ユーザーを疲れさせない
+</h3>
+
+<p>
+ ユーザーにパーミッションをたくさん要求すると、ユーザーを疲れさせてしまい、アプリが終了される原因になります。代わりに、ユーザーには必要なパーミッションのみを要求してください。
+
+
+</p>
+
+<p>
+ アプリ対して 1 つ以上のパーミッションが必須である場合もあります。その場合は、アプリの起動後すぐに、すべてのパーミッションを要求することが合理的である場合があります。
+
+たとえば、カメラアプリを作成する場合、アプリは端末のカメラにアクセスする必要があります。
+アプリを初めて起動するときにカメラの使用についてのパーミッションを求められても驚かないはずです。
+
+ただし、同じアプリにユーザーの連絡先と写真を共有する機能もある場合は、最初の起動時にパーミッションを要求<em>しない</em>方が無難です。
+
+その代わりに、ユーザーが「共有」機能を使うまで待ち、そのときにパーミッションを要求します。
+
+</p>
+
+<p>
+ アプリにチュートリアルが含まれる場合は、チュートリアルのシーケンスの最後で、アプリに必須のパーミッションを要求する方が合理的です。
+
+</p>
+
+<h3 id="bp-explain">
+ パーミッションが必要な理由を説明する
+</h3>
+
+<p>
+ <code>requestPermissions()</code> を呼び出すとき、システムによって表示されるパーミッション ダイアログにはアプリが必要としているパーミッションは表示されますが、理由は表示されません。
+
+これによりユーザーが困惑する場合もあります。
+ <code>requestPermissions()</code> を呼び出す前に、アプリがパーミッションを必要としている理由をユーザーに説明するのはよい方法です。
+
+</p>
+
+<p>
+ たとえば、カメラアプリでは、位置情報サービスを使って写真に位置情報タグを付けられるようにする場合があります。
+通常のユーザーは、写真に位置情報が含まれる場合があることを認識していない可能性があり、なぜカメラアプリで位置情報が必要なのか困惑する可能性があります。
+
+この場合、アプリが <code>requestPermissions()</code> を呼び出す<em>前</em>に、この機能についてユーザーに知らせることをお勧めします。
+
+
+</p>
+
+<p>
+ その方法として、これらの要求をアプリのチュートリアルに組み込むこともできます。チュートリアルでは、アプリの各機能を順番に表示できるので、必要なパーミッションを説明できます。
+
+たとえば、カメラアプリのチュートリアルでは、「連絡先と写真を共有する」機能について説明し、ユーザーの連絡先を参照するためにアプリにパーミッションが必要であることをユーザーに知らせることができます。
+
+
+その後、アプリは <code>requestPermissions()</code> を呼び出して、ユーザーにそのアクセスを求めることができます。
+もちろん、すべてのユーザーがチュートリアルに従うわけではないため、アプリの通常操作中にパーミッションを確認して要求することも必要です。
+
+
+</p>
diff --git a/docs/html-intl/intl/ja/preview/overview.jd b/docs/html-intl/intl/ja/preview/overview.jd
new file mode 100644
index 0000000..4cefdd1
--- /dev/null
+++ b/docs/html-intl/intl/ja/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=プログラム概要
+page.metaDescription=Android M Developer Preview では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ <strong>Android M Developer Preview</strong> では、Android の次のバージョンでアプリをテストして最適化するためのすべてを備えています。
+
+M Developer Preview ツールをダウンロードするだけで、無料ですぐにご利用いただけます。
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ ハードウェアとエミュレータのシステム イメージ
+ </h5>
+
+ <p>
+ Nexus 5、6、9、Nexus Player(TV 向け)やエミュレータでアプリをテストしましょう。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 最新プラットフォーム コード
+ </h5>
+
+ <p>
+ プレビューで複数のアップデートが提供されますので、最新プラットフォームの変更に応じてテストできます。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ OTA でのアップデート
+ </h5>
+
+ <p>
+ デバイスに初期プレビューをコピーしたら、無線経由でアップデートを入手できます。
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 新しい動作と機能
+ </h5>
+
+ <p>
+ 新しい実行時パーミッション モデルや省電力機能など、新しいプラットフォームの動作をあらかじめサポートする
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 開発者が報告した問題に対する優先度ウィンドウ
+ </h5>
+
+ <p>
+ 最初の数週間で開発者から報告のあった問題について優先度を設定し、可能な限り早くテストを行いフィードバックを提供できるようにします。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ フィードバックとサポート
+ </h5>
+
+ <p>
+ <a href="https://code.google.com/p/android-developer-preview/">Issue Tracker</a> で問題を報告し、フィードバックをお送りください。
+ <a href="http://g.co/dev/AndroidMDevPreview">M Developer コミュニティ</a> で他の開発者とつながりましょう。
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ タイムラインとアップデート
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M Developer Preview は 5 月 28 日から最終の Android M SDK まで実行されます。Android M SDK はまもなく、2015 年第三四半期に予定されている正式公開の前にリリースされます。
+
+
+</p>
+
+<p>
+ 開発の主なマイルストーンごとにテスト端末へアップデートを配信する予定としています。
+ 暫定マイルストーンは以下のとおりです。
+</p>
+
+<ul>
+ <li>
+ <strong>Preview 1</strong>(初期プレビュー リリース、5 月下旬)
+ </li>
+
+ <li>
+ <strong>Preview 2</strong>(6 月下旬/7 月上旬)
+ </li>
+
+ <li>
+ <strong>Preview 3</strong>(最終近く、7 月下旬)
+ </li>
+</ul>
+
+<p>
+ アップデートは第三四半期後半に予定されている<strong>最終 SDK</strong> で終了します。最終版では新しい Android に対する正式な API や最終的なシステム動作や機能が提供されます。
+
+
+</p>
+
+<p>
+ Android M でのテストや開発に際しては、Preview アップデートがリリースされるたびに<strong>開発環境を最新に保つ</strong>ことを強くお勧めします。
+
+ プロセスをより容易にするため、既に Preview ビルドがインストールされた端末に<strong>無線経由でアップデート(OTA)</strong>を配信します。また手動でダウンロードして展開できるシステム イメージもご提供します。
+
+
+</p>
+<p class="note">
+ <strong>注:</strong> 最終 SDK とシステム イメージは OTA では配信できません。代わりにテスト端末に<strong>手動でコピー</strong>する必要があります。</strong>
+
+
+</p>
+
+<p>
+ Preview アップデートをご利用いただけるようになった際は <a href="http://android-developers.blogspot.com/">Android デベロッパー ブログ</a>、このサイト、<a href="http://g.co/dev/AndroidMDevPreview">Android M デベロッパー コミュニティ</a>でお知らせします。
+
+
+</p>
+
+<h2 id="preview_tools">
+ Preview の内容
+</h2>
+
+<p>
+ M Developer Preview では、ご利用のアプリをさまざまな画面サイズ、ネットワーク、テクノロジー、CPU や GPU チップセット、ハードウェア設計でテストするために必要なあらゆるものを備えています。
+
+
+</p>
+
+<h4>
+ SDK ツール
+</h4>
+
+<p>
+ 各コンポーネントは <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> の SDK Manager でダウンロードできます。
+</p>
+
+<ul>
+ <li>M Developer Preview <strong>SDK ツール</strong>
+ </li>
+
+ <li>M Developer Preview <strong>エミュレータ システム イメージ</strong>(32 ビット版と 64 ビット版)
+
+ </li>
+
+ <li>M Developer Preview <strong>Android TV 版エミュレータ システム イメージ</strong>(32 ビット版)
+
+ </li>
+</ul>
+
+<h4>
+ ハードウェアのシステム イメージ
+</h4>
+
+<p>
+ Nexus 端末向けハードウェア システム イメージは、<a href="download.html">ダウンロード ページ</a>からダウンロードできます。
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong>(GSM と LTE)“hammerhead” 端末システム イメージ
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> “shamu” 端末システム イメージ
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong>(Wi-Fi)“volantis” 端末システム イメージ
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong>(AndroidTV)“fugu” 端末システム イメージ
+ </li>
+</ul>
+
+<h4>
+ ドキュメントとサンプル コード
+</h4>
+
+<p>
+ 次のドキュメント リソースで Preview についての詳細をご確認いただけます。
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">SDK のセットアップ</a>では、はじめの手順をステップ バイ ステップでご説明しています。
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Testing Guide</a> と <a href="behavior-changes.html">Behavior Changes</a> では、テストでカバーされる主な分野について示しています。
+ </li>
+
+ <li>新しい API のドキュメントである <a href="api-overview.html">API 概要</a>、ダウンロード可能な <a href="{@docRoot}preview/download.html#docs">API リファレンス</a>や、主な機能のデベロッパー ガイドである<a href="{@docRoot}preview/features/runtime-permissions.html">パーミッション</a>、<a href="{@docRoot}preview/backup/index.html">アプリのバックアップ</a>などをご提供しています。
+
+
+
+
+ </li>
+
+ <li>
+ パーミッションや他の新しい機能をサポートする方法について、<a href="{@docRoot}preview/samples.html">サンプル コード</a>でお試しいただけます。
+
+ </li>
+
+ <li>
+ 現行バージョンの<a href="{@docRoot}preview/support.html#release-notes">リリース ノート</a>で M Developer Preview の変更メモや差分レポートなどをご覧いただけます。
+
+ </li>
+</ul>
+
+<h4>
+ サポート リソース
+</h4>
+
+<p>
+ M Developer Preview でのテストや開発について、次のサポート リソースをご確認いただけます。
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">M Developer Preview Issue Tracker</a> は、<strong>主なフィードバック チャンネル</strong>としてご利用になれます。
+
+バグやパフォーマンスの問題、一般的なフィードバックなど Issue Tracker からご連絡いただけます。
+また、<a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">既知の問題</a>
+やその回避策をご確認いただけます。
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>は Google+ のコミュニティで、Android M を使っている<strong>他のデベロッパーとつながる</strong>ことができます。Android M に関する現象や考えを共有したり、疑問点を解消したりできます。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 対象、プレビュー API、公開
+</h2>
+
+<p>
+ Android M Developer Preview は開発リリースのみであり、<strong>標準 API レベルはありません</strong>。
+アプリのテストで互換性の問題は除外する場合(強く推奨します)、アプリの<code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> を <code>“MNC”</code> に設定することで M Developer Preview を対象にできます。
+
+
+
+</p>
+
+<p>
+ Android M Developer Preview では<strong>プレビュー API</strong> を配信しています。現在 2015 年度第三四半期に予定されている最終 SDK がリリースされるまで、API は正式版ではありません。
+
+つまり、時間がたつにつれて <strong>API の細かな変更</strong>が見込まれます(特にプログラムの最初の数週間)。
+
+Android M Developer Preview でアップデートがあればその都度変更の概要をご提供します。
+
+</p>
+
+<p class="note">
+ プレビュー API は変更される可能性がありますが、実行時パーミッションや省電力機能などのシステムの基幹にかかわる機能には変更はありませんので、すぐにテストしていただけます。
+
+
+</p>
+
+<p>
+ 公開に関して、Google Play では <strong>M Developer Preview 対象アプリは公開できません</strong>。
+Android M 最終 SDK が利用可能になれば正式な Android M API レベルを対象にして、Google Play でアプリを公開できるようになります。
+
+それまでは、Android M 対象のアプリをテスターに配布する場合は電子メールで送付したりご自分のサイトから直接ダウンロードしてもらったりしてください。
+
+
+</p>
+
+<h2 id="get_started">
+ 開始するには
+</h2>
+
+<p>
+ アプリのテストをはじめるには:
+</p>
+
+<ol>
+ <li><a href="{@docRoot}preview/api-overview.html">API 概要</a>や <a href="{@docRoot}preview/behavior-changes.html">Behavior Changes</a> で新しい機能やご自分のアプリへの影響についてご確認ください。
+
+特に、<a href="{@docRoot}preview/features/runtime-permissions.html">実行時パーミッション</a> モデルや省電力機能、自動バックアップ機能についてお確かめください。
+
+
+ </li>
+
+ <li><a href="{@docRoot}preview/setup-sdk.html">Setting up the Preview SDK</a> の手順に従い、ご利用の環境をセットアップしてテスト端末を構成してください。
+
+
+ </li>
+
+ <li><a href="https://developers.google.com/android/nexus/images">コピー手順</a>に従い、最新の M Developer Preview システム イメージを Nexus 5、6、9、Nexus Player にコピーします。
+
+1 度開発端末に Preview 環境をコピーすると、アップデートが無線経由(OTA)で配信されます。</a>
+
+ </li>
+
+ <li><a href="{@docRoot}preview/download.html#docs">M Preview API リファレンス</a>や<a href="{@docRoot}preview/samples.html">M Preview サンプル</a>をダウンロードして、新しい API の機能についてさらに学び、ご自分のアプリで活用する方法についてご確認ください。
+
+
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M Developer コミュニティ</a>に参加して最新のニュースを入手し、Preview に取り組んでいる他のデベロッパーとつながってください。
+
+
+ </li>
+</ol>
+
+<p>
+ Android M Developer Preview プログラムへのご参加ありがとうございます。
+</p>
diff --git a/docs/html-intl/intl/ko/preview/api-overview.jd b/docs/html-intl/intl/ko/preview/api-overview.jd
new file mode 100644
index 0000000..aac9a44
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=API 개요
+page.keywords=미리 보기, SDK, 호환성
+page.tags=previewresources, androidm
+sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">더 보기</span>
+ <span class="less" style="display:none">숨기기</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">앱 연결</a></li>
+ <li><a href="#backup">앱용 자동 백업</a></li>
+ <li><a href="#authentication">인증</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">지문 인증</a></li>
+ <li><a href="#confirm-credential">확인 자격 증명</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">직접 공유</a></li>
+ <li><a href="#voice-interactions">음성 상호작용</a></li>
+ <li><a href="#assist">지원 API</a></li>
+ <li><a href="#notifications">알림</a></li>
+ <li><a href="#bluetooth-stylus">블루투스 스타일러스 지원</a></li>
+ <li><a href="#ble-scanning">블루투스 저전력 스캔 개선</a></li>
+ <li><a href="#hotspot">핫스팟 2.0 릴리스 1 지원</a></li>
+ <li><a href="#4K-display">4K 디스플레이 모드</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">테마 지정 가능 ColorStateLists</a></li>
+ <li><a href="#audio">오디오 기능</a></li>
+ <li><a href="#video">비디오 기능</a></li>
+ <li><a href="#camera">카메라 기능</a>
+ <ol>
+ <li><a href="#flashlight">Flashlight API</a></li>
+ <li><a href="#reprocessing">카메라 재처리</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Android for Work 기능</a></li>
+</ol>
+
+<h2>API 차이점</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">M 미리 보기에 대한 API 레벨 22 »</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M 개발자 미리 보기에서는 다가오는 Android 플랫폼 릴리스를 미리 볼 수 있도록 하였습니다. 이 릴리스는 사용자와 앱 개발자를 위한 여러 가지 새 기능을 제공합니다.
+
+ 이 문서에서는 가장 중요한 API를 몇 가지 소개합니다.</p>
+
+<p>M 개발자 미리 보기는 <strong>개발자 얼리 어답터</strong>와 <strong>테스터</strong>를 위해 마련된 것입니다.
+ Android 프레임워크가 나아갈 방향에 영향을 미치는 데 관심이 있으시다면, <a href="{@docRoot}preview/setup-sdk.html">M 개발자 미리 보기를 시도해 보시고</a> 피드백을 보내주세요!
+
+
+</p>
+
+<p class="caution"><strong>주의:</strong> M 개발자 미리 보기를 사용하는 앱을 Google Play 스토어에 게시하지 마세요.
+</p>
+
+<p class="note"><strong>참고:</strong> 이 문서에서 종종 언급하는 클래스와 메서드 중에는 아직 <a href="{@docRoot}">developer.android.com</a>에서 참조 자료로 이용할 수 없는 것도 있습니다.
+ 이와 같은 API 요소는 이 문서에서 {@code code style}로 형식 지정되어 있습니다(하이퍼링크 없이).
+ 이러한 요소에 대한 임시 API 관련 문서가 필요한 경우, <a href="{@docRoot}preview/download.html#docs">미리 보기 참조</a>를 다운로드하세요.
+</p>
+
+<h3>중요한 동작 변경</h3>
+
+<p>이전에 Android용 앱을 게시한 적이 있는 경우, 플랫폼 변경으로 인해 앱이 영향받을 수 있다는 점을 유의하세요.
+</p>
+
+<p>완전한 정보는 <a href="behavior-changes.html">동작 변경</a>을 참조하세요.</p>
+
+<h2 id="app-linking">앱 연결</h2>
+<p>이 미리 보기는 더욱 강력한 앱 연결을 제공하여 Android의 인텐트 시스템을 한층 강화합니다. 이 기능을 사용하면 앱을 본인이 소유한 웹 도메인과 연관시킬 수 있습니다.
+ 플랫폼은 이 연관 관계를 근거로 특정한 웹 링크를 처리하는 데 사용할 기본 앱을 결정할 수 있고 사용자에게 앱을 선택하라는 메시지를 건너뛸 수 있습니다. 이 기능을 구현하는 방법을 알아보려면 <a href="{@docRoot}preview/features/app-linking.html">앱 연결</a>을 참조하세요.
+
+
+
+
+<h2 id="backup">앱용 자동 백업</h2>
+<p>시스템에서 이제 앱에 대한 완전한 데이터 백업과 복원을 자동으로 수행합니다. 이 동작은 앱 대상 지정 M 미리 보기에 대한 기본으로 활성화되며, 추가 코드를 전혀 추가하지 않아도 됩니다.
+ 사용자가 Google 계정을 삭제하면 계정의 백업 데이터도 함께 삭제됩니다.
+ 이 기능의 작동 원리와 파일 시스템에서 백업 내용 구성하는 방법에 대해 알아보려면 <a href="{@docRoot}preview/backup/index.html">앱용 자동 백업</a>을 참조하세요.
+
+</p>
+
+<h2 id="authentication">인증</h2>
+<p>이 미리 보기에서는 사용자를 인증할 때 지원되는 기기에서 지문 스캔을 사용하도록 해주는 새로운 API를 제공합니다. 또한 기기 잠금 해제 메커니즘(예: 화면 잠금 비밀번호)을 사용해 사용자의 마지막 인증 시간을 확인할 수도 있습니다.
+
+ 이러한 API는 <a href="{@docRoot}training/articles/keystore.html">Android Keystore 시스템</a>과 함께 사용하세요.
+</p>
+
+<h3 id="fingerprint-authentication">지문 인증</h3>
+
+<p>지문 스캔을 통해 사용자를 인증하려면 새로운 {@code android.hardware.fingerprint.FingerprintManager} 클래스의 인스턴스를 가져와 {@code FingerprintManager.authenticate()} 메서드를 호출하세요.
+
+ 앱이 지문 센서가 있는 호환되는 기기에서 실행되고 있어야 합니다.
+ 지문 인증 흐름에 대한 사용자 인터페이스를 앱에 구현해야 하며, UI에 표준 Android 지문 아이콘을 사용해야 합니다. 이 Android 지문 아이콘({@code c_fp_40px.png})은 <a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">샘플 앱</a>에 포함되어 있습니다. 지문 인증을 사용하는 앱을 여러 개 개발하는 경우, 각 앱이 사용자의 지문을 따로따로 인증해야 한다는 사실을 명심하세요.
+
+
+
+
+</p>
+
+<p>앱에서 이 기능을 사용하려면 우선 매니페스트에 {@code USE_FINGERPRINT} 권한을 추가해야 합니다.
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>지문 인증의 앱 구현을 확인하려면, <a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">지문 대화 샘플</a>을 참조하세요.
+
+</p>
+
+<p>이 기능을 테스트하는 경우, 다음 단계를 따르면 됩니다.</p>
+<ol>
+<li>아직 Android SDK 도구 수정 버전 24.3을 설치합니다(설치하지 않은 경우).</li>
+<li>에뮬레이터에 새 지문을 등록하려면 <strong>설정 > 보안 > 지문</strong>으로 이동한 다음, 등록 지침을 따르면 됩니다.
+</li>
+<li>에뮬레이터를 사용하여 지문 터치 이벤트를 에뮬레이트하되 다음 명령을 사용하세요.
+ 잠금 화면이나 앱에서 지문 터치 이벤트를 에뮬레이트할 때에도 같은 명령을 사용합니다.
+
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>Windows에서는 {@code telnet 127.0.0.1 <emulator-id>}에 뒤이어 {@code finger touch <finger_id>}를 실행해야 할 수도 있습니다.
+
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">확인 자격 증명</h3>
+<p>앱에서 사용자를 인증할 때 해당 사용자가 기기를 마지막으로 잠금 해제한 시간을 근거로 할 수 있습니다. 이 기능을 사용하면 사용자가 앱에 따라 각기 다른 비밀번호를 기억할 필요가 없어지고, 개발자는 자신만의 인증 사용자 인터페이스를 구현하지 않아도 됩니다.
+
+ 앱에서 이 기능을 사용하려면 사용자 인증에 대한 공개 또는 비밀 키 구현과 함께 사용해야 합니다.
+</p>
+
+<p>사용자를 성공적으로 인증한 다음 같은 키를 재사용하기 위한 시간 초과 기간을 설정하려면, 새로운 {@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()} 메서드를 호출하세요. {@link javax.crypto.KeyGenerator} 또는 {@link java.security.KeyPairGenerator}를 설정할 때 사용하면 됩니다.
+
+
+
+ 현재 이 기능은 대칭형 암호화 작동에 맞게 작동합니다.
+</p>
+
+<p>재인증 대화창을 과도하게 표시하는 것을 삼가세요. 우선 앱에서 암호화 객체 사용을 시도해보고, 제한 시간이 만료되면 {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} 메서드를 사용해 앱 내에서 해당 사용자를 재인증하면 됩니다.
+
+
+
+</p>
+
+<p>이 기능의 앱 구현을 확인하려면, <a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">확인 자격 증명 샘플</a>를 참조하세요.
+
+</p>
+
+<h2 id="direct-share">직접 공유</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>이 미리 보기에서는 사용자가 공유 기능을 간편하고 신속하게 이용할 수 있도록 해주는 API를 제공합니다. 이제 앱에서 특정 액티비티를 시작하는 <em>직접 공유 대상</em>을 정의할 수 있습니다. 이와 같은 직접 공유 대상은 <em>공유</em> 메뉴를 통해 사용자에게 노출됩니다.
+
+ 이 기능을 사용하면 사용자가 다른 앱 내의 대상(예: 연락처)에 대해 콘텐츠를 공유할 수 있습니다.
+ 예를 들어, 직접 공유 대상이 다른 소셜 네트워크 앱에서 액티비티를 시작하면 사용자가 해당 앱에 있는 특정 친구나 커뮤니티와 콘텐츠를 공유할 수 있습니다.
+
+</p>
+
+<p>직접 공유 대상을 활성화하려면 반드시 {@code android.service.}
+ <br>
+{@code chooser.ChooserTargetService} 클래스를 확장하는 클래스를 정의해야 합니다. 매니페스트에서 {@code ChooserTargetService}를 선언하고
+ 해당 선언 내에서 {@code BIND_CHOOSER_TARGET_SERVICE} 권한을 지정하고 {@code SERVICE_INTERFACE} 작업으로 인텐트 필터를 지정합니다.
+
+</p>
+<p>다음 예는 매니페스트에서 {@code ChooserTargetService}를 선언할 수 있는 방법입니다.
+</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>{@code ChooserTargetService}에 노출하고자 하는 액티비티마다 {@code <meta-data>} 요소를 하나씩 추가하고, 앱 매니페스트에 {@code "android.service.chooser.chooser_target_service"} 이름을 추가합니다.
+
+
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">음성 상호작용</h2>
+<p>
+이 미리 보기에서 제공하는 새로운 음성 상호작용 API는 <a href="https://developers.google.com/voice-actions/" class="external-link">음성 액션</a>과 같이 앱에 대화형 음성 환경을 구축할 수 있도록 합니다.
+
+ {@code android.app.Activity.isVoiceInteraction()} 메서드를 호출하여 액티비티가 음성 액션에 대응하여 시작된 것인지 알아보세요.
+
+ 이 경우에 해당되면, 앱이 {@code android.app.VoiceInteractor} 클래스를 사용하여 사용자로부터 음성 확인을 요청하거나, 선택 항목 목록에서 선택하게 하는 등 여러 가지 일을 할 수 있습니다.
+
+ 음성 액션 구현에 대한 자세한 정보는 <a href="https://developers.google.com/voice-actions/interaction/" class="external-link">음성 액션 개발자 사이트</a>를 참조하세요.
+
+</p>
+
+<h2 id="assist">지원 API</h2>
+<p>
+이 미리 보기에서는 사용자가 도우미를 통해 앱에 참여하게 하는 새로운 방식을 제시합니다. 이 기능을 사용하려면, 사용자가 현재 컨텍스트를 사용하기 위해 도우미를 활성화해야 합니다.
+ 일단 활성화하고 나면 <strong>홈</strong> 버튼을 길게 눌러 해당 도우미를 어느 앱에서나 불러낼 수 있습니다.
+</p>
+<p>앱이 현재 컨텍스트를 도우미와 공유하지 않기로 선택하는 경우, {@link android.view.WindowManager.LayoutParams#FLAG_SECURE} 플래그를 설정하면 됩니다.
+ 플랫폼이 도우미에게 전달하는 일반적인 일련의 정보 외에도 앱이 추가적인 정보를 공유할 수 있도록 하려면 새로 나온 {@code android.app.Activity.AssistContent} 클래스를 사용할 수 있습니다.
+
+</p>
+
+<p>도우미에게 앱에서 가져온 추가 컨텍스트를 제공하려면, 다음 단계를 따르면 됩니다.</p>
+
+<ol>
+<li>{@link android.app.Application.OnProvideAssistDataListener} 인터페이스를 구현합니다.</li>
+<li>{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}를 사용하여 이 수신기를 등록합니다.
+</li>
+<li>액티비티에 따라 각기 다른 상황별 정보를 제공하려면 {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} 콜백을 재정의하고, 선택 사항으로 새로운 {@code Activity.onProvideAssistContent()} 콜백도 재정의합니다.
+
+
+</ol>
+
+<h2 id="notifications">알림</h2>
+<p>이 미리 보기에서는 알림 기능에 다음과 같은 API 변경을 추가합니다.</p>
+<ul>
+ <li>새 {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} 필터 수준이 추가되었습니다. 이것은 새로운 <em>알람 전용</em> 방해 금지 모드에 상응하는 것입니다.
+</li>
+ <li>새 {@code Notification.CATEGORY_REMINDER} 카테고리 값이 추가되었습니다. 이것은 다른 이벤트로부터 사용자가 일정을 지정한 미리 알림({@link android.app.Notification#CATEGORY_EVENT}) 및 알람({@link android.app.Notification#CATEGORY_ALARM})를 구분하는 데 사용됩니다.
+
+
+</li>
+ <li>새 {@code android.graphics.drawable.Icon} 클래스가 추가되었습니다. 이것은 {@code Notification.Builder.setSmallIcon(Icon)} 및 {@code Notification.Builder.setLargeIcon(Icon)} 메서드를 통해 알림에 첨부할 수 있습니다.
+
+</li>
+ <li>새 {@code NotificationManager.getActiveNotifications()} 메서드가 추가되었습니다. 이것을 사용하면 앱이 자신의 알림 중 현재 활성 상태인 것이 무엇인지 알아낼 수 있습니다.
+ 이 기능을 사용하는 앱 구현을 확인하려면 <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">활성 알림 샘플</a>을 참조하세요.
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">블루투스 스타일러스 지원</h2>
+<p>이 미리 보기에서는 블루투스 스타일러스를 사용하는 사용자 입력에 대한 지원을 개선하여 제공합니다. 사용자는 전화기나 태블릿을 호환되는 블루투스 스타일러스와 페어링하고 이에 연결할 수 있습니다.
+ 연결된 동안 터치 스크린에서 가져온 위치 정보가 스타일러스에서 가져온 압력 및 버튼 정보와 합쳐져 하나의 터치 스크린을 사용할 때보다 훨씬 폭넓은 표현을 제공합니다.
+
+ 앱이 스타일러스 버튼 누르기를 수신 대기하고 보조 작업을 수행하도록 하려면, 액티비티에 새로운 {@code View.onStylusButtonPressListener} 및 {@code GestureDetector.OnStylusButtonPressListener} 콜백을 등록하면 됩니다.
+
+
+</p>
+
+<p>스타일러스 버튼 상호작용을 감지하려면 {@link android.view.MotionEvent} 메서드와 상수를 사용하세요.
+</p>
+<ul>
+<li>사용자가 앱의 화면에 있는 버튼으로 스타일러스를 터치하면 {@link android.view.MotionEvent#getToolType(int) getTooltype()} 메서드가 {@link android.view.MotionEvent#TOOL_TYPE_STYLUS}를 반환합니다.
+
+</li>
+<li>M 미리 보기를 대상으로 삼는 앱의 경우, {@link android.view.MotionEvent#getButtonState() getButtonState()} 메서드는 사용자가 기본 스타일러스 버튼을 누르면 {@code MotionEvent.STYLUS_BUTTON_PRIMARY}를 반환합니다.
+
+
+ 스타일러스에 두 번째 버튼이 있는 경우, 사용자가 그것을 누르면 같은 메서드가 {@code MotionEvent.STYLUS_BUTTON_SECONDARY}를 반환합니다.
+ 사용자가 두 버튼을 동시에 누르는 경우, 이 메서드는 두 값을 'OR'로 함께 묶어 모두 반환합니다({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).
+
+</li>
+<li>
+더 낮은 플랫폼 버전을 대상으로 하는 앱의 경우, {@link android.view.MotionEvent#getButtonState() getButtonState()} 메서드가 {@link android.view.MotionEvent#BUTTON_SECONDARY}(기본 스타일러스 버튼 누름)를 반환하고, {@link android.view.MotionEvent#BUTTON_TERTIARY}(보조 스타일러스 버튼 누름)를 반환하거나 둘 모두를 반환합니다.
+
+
+
+</li>
+</ul>
+
+<h2 id="ble-scanning">블루투스 저전력 스캔 개선</h2>
+<p>
+앱이 블루투스 저전력 스캔을 수행하는 경우, 새로운 {@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} 메서드를 사용해 콜백에 알림을 원하는 시점을 지정할 수 있습니다.즉, 정해진 {@link android.bluetooth.le.ScanFilter}에 일치하는 광고 패킷을 처음 찾았을 때와 이것을 일정한 시간 동안 확인하지 못했을 때에만 콜백에 알리도록 하면 됩니다.
+
+
+
+ 스캔 기능에 대해 이런 식으로 접근하면 이전 버전의 플랫폼에서 제공되었던 것에 비해 훨씬 전력 효율적입니다.
+
+</p>
+
+<h2 id="hotspot">핫스팟 2.0 릴리스 1 지원</h2>
+<p>
+이 미리 보기에서는 Nexus 6 및 Nexus 9 기기에서의 핫스팟 2.0 릴리스 1 사양에 대한 지원을 추가합니다. 앱에 핫스팟 2.0 자격 증명을 프로비저닝하려면 {@link android.net.wifi.WifiEnterpriseConfig} 클래스의 새 메서드를 사용할 수 있습니다(예: {@code setPlmn()} 및 {@code setRealm()}).
+
+
+ {@link android.net.wifi.WifiConfiguration} 객체에서는 {@link android.net.wifi.WifiConfiguration#FQDN} 및 {@code providerFriendlyName} 필드를 설정하면 됩니다. 새로 나온 {@code ScanResult.PasspointNetwork} 속성이 감지된 네트워크가 핫스팟 2.0 액세스 지점을 나타내는지 여부를 알려줍니다.
+
+
+
+</p>
+
+<h2 id="4K-display">4K 디스플레이 모드</h2>
+<p>이제 플랫폼에서 앱이 호환되는 하드웨어에서 디스플레이 해상도를 4K 렌더링으로 업그레이드하도록 요청할 수 있습니다.
+ 현재의 물리적 해상도를 쿼리하려면 새로운 {@code android.view.Display.Mode} API를 사용할 수 있습니다.
+ UI가 더 낮은 논리적 해상도에서 그려졌고 더 큰 물리적 해상도에 맞춰 확장된 경우, {@code Display.Mode.getPhysicalWidth()} 메서드가 반환하는 물리적 해상도가 {@link android.view.Display#getSize(android.graphics.Point) getSize()}가 보고하는 논리적 해상도와 다를 수 있다는 점을 유의하세요.
+
+
+</p>
+
+<p>앱이 실행되는 중에 시스템에 물리적 해상도를 변경하도록 요청할 수도 있습니다. 앱의 창에서 {@code WindowManager.LayoutParams.preferredDisplayModeId} 속성을 설정하면 됩니다.
+ 이 기능은 4K 디스플레이 해상도로 전환하고자 하는 경우 무척 유용합니다.
+ 4K 디스플레이 모드에서 UI는 계속 원래 해상도(예: 1080p)에서 렌더링되며 4K로 확장되지만, {@link android.view.SurfaceView} 객체는 원래 해상도에서 콘텐츠를 표시할 수 있습니다.
+
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">테마 지정 가능 ColorStateLists</h2>
+<p>이제 M 미리 보기를 실행하는 기기에 대해 테마 속성이 {@link android.content.res.ColorStateList}에서 지원됩니다.
+ {@link android.content.res.Resources#getColorStateList(int) getColorStateList()} 및 {@link android.content.res.Resources#getColor(int) getColor()} 메서드는 사용이 중단되었습니다.
+
+ 이러한 API를 호출하려면, 대신 새로운 {@code Context.getColorStateList()} 또는 {@code Context.getColor()} 메서드를 호출하세요.
+
+ 이 두 메서드는 v4 AppCompat 라이브러리에서도 {@link android.support.v4.content.ContextCompat}를 통해 이용할 수 있습니다.
+</p>
+
+<h2 id="audio">오디오 기능</h2>
+
+<p>이 미리 보기에서는 Android에서의 오디오 처리에 개선점을 더했습니다. </p>
+<ul>
+ <li><a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> 프로토콜을 지원하는 새로운 {@code android.media.midi} API를 추가했습니다.
+ 이와 같은 API를 사용하면 MIDI 이벤트를 전송 및 수신할 수 있습니다.
+</li>
+ <li>새 {@code android.media.AudioRecord.Builder} 및 {@code android.media.AudioTrack.Builder} 클래스를 추가하여 각각 디지털 오디오 캡처와 재생 객체를 생성하고, 오디오 소스와 싱크 속성을 구성하여 시스템 기본 설정을 재정의하도록 하였습니다.
+
+</li>
+ <li>오디오 및 입력 기기를 연관시키기 위한 API Hook이 추가되었습니다. 이것은 특히 앱이 사용자에게 게임 컨트롤러 또는 Android TV에 연결된 리모컨에서 음성을 검색하는 데 유용합니다. 사용자가 검색을 시작하면 시스템이 새로운 {@code android.app.Activity.onSearchRequested()} 콜백을 호출합니다.
+
+
+ 사용자의 입력 기기에 마이크가 내장되어 있는지 판별하려면, 해당 콜백에서 {@link android.view.InputDevice} 객체를 검색한 다음 새 {@code InputDevice.hasMic()} 메서드를 호출하면 됩니다.
+
+</li>
+ <li>새 {@code android.media.AudioDevicesManager} 클래스를 추가하여 첨부된 소스와 싱크 오디오 기기 전체 목록을 검색할 수 있습니다.
+ 이외에도, {@code android.media.OnAudioDeviceConnectionListener} 객체를 지정하여 오디오 기기가 연결되거나 연결 해제되었을 때 앱에 알릴 수도 있습니다.
+
+</li>
+</ul>
+
+<h2 id="video">비디오 기능</h2>
+<p>이 미리 보기에서는 비디오 처리 API에 새로운 기능을 추가합니다.</p>
+<ul>
+<li>새 {@code android.media.MediaSync} 클래스를 추가하여 여러 애플리케이션이 오디오와 비디오 스트림을 동기적으로 렌더링하는 데 지원하도록 하였습니다.
+ 오디오 버퍼는 비블로킹 방식으로 제출된 다음 콜백을 통해 반환됩니다.
+ 이것은 동적 재생 속도도 지원합니다.
+</li>
+<li>새 {@code MediaDrm.EVENT_SESSION_RECLAIMED} 이벤트를 추가하여 앱이 연 세션을 리소스 관리자가 회수했다는 내용을 나타낼 수 있습니다.
+ 앱이 DRM 세션을 사용하는 경우, 이 이벤트를 처리해야 하고 회수된 세션을 사용하지 않도록 해야 합니다.
+
+</li>
+<li>새 {@code MediaCodec.CodecException.ERROR_RECLAIMED} 오류 코드를 추가했습니다. 이것은 코덱이 사용하는 미디어 리소스를 리소스 관리자가 회수했다는 내용을 나타냅니다.
+ 이런 경우를 예외로 하고, 코덱은 종료 상태로 이동하면서 해제되어야 합니다.
+
+</li>
+<li>새 {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} 인터페이스를 추가하여 지원되는 동시 코덱 인스턴스의 최대 수에 대한 힌트를 얻을 수 있습니다.
+
+</li>
+<li>새 {@code MediaPlayer.setPlaybackParams()} 메서드로는 빠른 재생 또는 느린 동작 재생에 대한 미디어 재생 속도를 설정할 수 있습니다.
+ 이는 또한 비디오와 함께 오디오 재생을 자동으로 늘리거나 속도를 높이기도 합니다.
+</li>
+</ul>
+
+<h2 id="camera">카메라 기능</h2>
+<p>이 미리 보기에는 다음과 같은 새 API를 제공하여 카메라의 플래시에 액세스하고 이미지를 재처리하는 카메라에 액세스할 수 있도록 했습니다.
+</p>
+
+<h3 id="flashlight">Flashlight API</h3>
+<p>카메라 기기에 플래시 장치가 있는 경우, {@code CameraManager.setTorchMode()} 메서드를 호출하여 카메라 기기를 열지 않고도 플래시 장치의 Torch 모드를 켜거나 끌 수 있습니다.
+ 앱에는 플래시 장치 또는 카메라 기기에 대한 독점적인 소유권이 없습니다.
+ Torch 모드는 꺼져 있다가 카메라 기기를 이용할 수 없게 될 때마다 이용 불가능한 상태가 되고, Torch 모드를 켜진 상태로 유지하던 다른 카메라 리소스를 이용할 수 없게 되면 이용 불가능하게 됩니다.
+
+ 다른 앱도 {@code setTorchMode()}를 호출하여 Torch 모드를 끌 수 있습니다.
+ Torch 모드를 켠 마지막 앱이 종료되면 Troch 모드도 꺼집니다.
+</p>
+
+<p>Torch 모드 상태에 대해 알림을 받기 위한 콜백을 등록하려면 {@code CameraManager.registerTorchCallback()} 메서드를 호출하면 됩니다.
+ 콜백을 처음 등록하면 그 즉시, 현재 알려진 모든 카메라 기기(플래시 장치가 있는)의 Torch 모드 상태와 함께 호출됩니다.
+
+ Torch 모드가 성공적으로 켜지거나 꺼지면 {@code CameraManager.TorchCallback.onTorchModeChanged()} 메서드가 불려나옵니다.
+</p>
+
+<h3 id="reprocessing">재처리 API</h3>
+<p>{@link android.hardware.camera2 Camera2} API를 확장하여 YUV를 지원하고 비공개 불투명 형식 이미지 재처리를 지원하게 되었습니다.
+ 앱은 재처리 기능을 이용할 수 있는지 알아보기 위해 {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}를 통합니다.
+ 기기가 재처리를 지원하는 경우, 재처리 가능한 카메라 캡처 세션을 생성하려면 {@code CameraDevice.createReprocessableCaptureSession()}을 호출하고 입력 버퍼 재처리를 위한 요청을 생성하면 됩니다.
+
+
+</p>
+
+<p>{@code ImageWriter} 클래스를 사용하여 카메라 재처리 입력에 입력 버퍼 흐름을 연결시키세요.
+ 빈 버퍼를 가져오려면 다음과 같은 프로그래밍 모델을 따르면 됩니다.</p>
+
+<ol>
+<li>{@code ImageWriter.dequeueInputImage()} 메서드를 호출합니다.</li>
+<li>입력 버퍼에 이 데이터를 채웁니다.</li>
+<li>{@code ImageWriter.queueInputImage()} 메서드를 호출하여 해당 버퍼를 카메라에 전송합니다.</li>
+</ol>
+
+<p>{@code ImageWriter} 객체와 {@code android.graphics.ImageFormat.PRIVATE} 이미지를 함께 사용하는 경우, 앱이 이미지 데이터에 직접 액세스할 수 없습니다.
+
+ 대신, 버퍼 사본 없이 {@code ImageWriter.queueInputImage()} 메서드를 호출하여 {@code ImageFormat.PRIVATE} 이미지를 {@code ImageWriter}에 직접 전달하면 됩니다.
+
+</p>
+
+<p>이제 {@code ImageReader} 클래스가 {@code android.graphics.ImageFormat.PRIVATE} 형식 이미지 스트림을 지원합니다.
+ 이로써 앱이 {@code ImageReader} 출력 이미지의 원형 이미지 대기열을 유지하고 하나 이상의 이미지를 선택하여 이들을 {@code ImageWriter}에 보내 카메라 재처리를 할 수 있습니다.
+
+</p>
+
+<h2 id="afw">Android for Work 기능</h2>
+<p>이 미리 보기에는 다음과 같은 Android for Work에 대한 새 API가 포함되어 있습니다.</p>
+<ul>
+ <li><strong>회사 소유, 일회용 기기 제어 능력 향상:</strong> 이제 기기 소유자가 다음과 같은 설정을 제어하여 회사 소유, 일회용(COSU) 기기 관리를 한층 개선할 수 있습니다.
+
+
+ <ul>
+ <li>키가드를 비활성화하거나 다시 활성화하려면 {@code DevicePolicyManager.setKeyguardEnabledState()} 메서드를 사용하세요.
+</li>
+ <li>상태 표시줄(빠른 설정, 알림과 Google Now를 시작하는 탐색 스와이프 업 동작 포함)을 비활성화하거나 다시 활성화하려면 {@code DevicePolicyManager.setStatusBarEnabledState()} 메서드를 사용하세요.
+
+</li>
+ <li>안전 부팅을 비활성화하거나 다시 활성화하려면 {@link android.os.UserManager} 상수 {@code DISALLOW_SAFE_BOOT}를 사용하세요.
+</li>
+ <li>플러그인 상태에서 화면이 꺼지지 않도록 방지하려면 {@link android.provider.Settings.Global} 상수 {@code STAY_ON_WHILE_PLUGGED_IN}을 사용하세요.
+</li>
+ </ul>
+ </li>
+ <li><strong>기기 소유자의 앱 자동 설치 및 설치 제거:</strong> 이제 기기 소유자가 애플리케이션을 자동으로 설치하고 제거할 수 있습니다. 업무용 Google Play와는 따로 {@link android.content.pm.PackageInstaller} API를 사용하면 됩니다.
+
+ 이제 사용자 상호작용 없이도 앱을 가져오고 설치하는 기기 소유자를 통해 기기를 프로비저닝할 수 있습니다.
+ 이 기능은 Google 계정을 활성화하지 않고도 키오스크 또는 그와 같은 다른 기기를 원터치 방식으로 프로비저닝하는 데 유용합니다.
+</li>
+<li><strong>자동 엔터프라이즈 인증서 액세스: </strong> 사용자에게 인증서를 선택하라는 메시지가 표시되기 전에 앱이{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()}를 호출하는 경우, 이제 프로필 또는 기기 소유자가 {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()}를 호출하여 요청하는 애플리케이션에 자동으로 별칭을 제공할 수 있습니다.
+
+
+
+ 이 기능을 사용하면 관리된 앱에 사용자 상호작용 없이도 인증서에 대한 액세스 권한을 부여할 수 있습니다.
+</li>
+<li><strong>시스템 업데이트 자동 수락:</strong> 시스템 업데이트 정책을 {@code DevicePolicyManager.setSystemUpdatePolicy()}로 설정하면, 이제 기기 소유자가 자동으로 시스템 업데이트를 수락할 수 있습니다(예: 키오스크 기기의 경우). 또는 업데이트를 연기하거나 사용자가 업데이트를 수행하지 못하도록 최대 30일까지 막을 수 있습니다.
+
+
+ 이에 더해, 관리자가 매일 시간 창을 설정하여 여기에서 업데이트를 수행하도록 할 수 있습니다. 예를 들어, 키오스크 기기를 사용하지 않는 시간 중에 업데이트하도록 합니다.
+ 시스템 업데이트를 사용할 수 있게 되면 시스템이 작업 정책 컨트롤러 앱에 시스템 업데이트 정책이 설정되어 있는지 확인하고, 그에 따라 동작합니다.
+
+
+</li>
+<li>
+<strong>인증서 설치 위임:</strong> 이제 프로필 또는 기기 소유자가 타사 앱에 권한을 부여하여 다음과 같은 {@link android.app.admin.DevicePolicyManager} 인증서 관리 API를 호출할 수 있습니다.
+
+
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>엔터프라이즈 공장 재설정 보호:</strong> 기기 소유자를 프로비저닝하는 경우, 이제 {@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} 번들을 설정하여 공장 재설정 보호(FRP)를 잠금 해제하는 데 사용되는 매개변수를 구성할 수 있습니다.
+
+ 이와 같은 매개변수는 기기를 재설정하여 FRP를 잠금 해제하도록 하고 기기를 프로비저닝하기로 한 다음에 NFC 프로그래머 앱이 제공할 수 있으며, 이전에 구성한 Google 계정도 필요하지 않습니다.
+
+ 이와 같은 매개변수를 수정하지 않으면 FRP가 제자리에 유지되어 이전에 활성화한 Google 자격 증명 없이는 기기가 활성화되지 않도록 방지합니다.
+
+
+<p>이외에도 Google Play 서비스에 앱 제한을 설정하면 기기 소유자가 기기에서 활성화된 것을 대신할 대체 Google 계정을 지정하여 FRP를 잠금 해제하는 데 사용할 수 있습니다.
+</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>데이터 사용량 추적:</strong> 새로운 {@code android.app.usage.NetworkStatsManager} 메서드를 사용하여 이제 프로필 또는 기기 소유자가 <strong>설정 > 데이터</strong>에 표시되는 데이터 사용량 통계를 쿼리할 수 있습니다.
+
+ 프로필 소유자에게는 자신이 관리하는 프로필에서 데이터를 쿼리할 권한이 자동으로 부여되는 반면, 기기 소유자의 경우에는 관리된 기본 사용자의 사용량 데이터에 대한 액세스 권한이 주어집니다.
+
+</li>
+<li><strong>런타임 권한 관리:</strong>
+<p>프로필 또는 기기 소유자는 모든 애플리케이션의 모든 런타임 요청에 대해 권한 정책을 설정할 수 있습니다. {@code DevicePolicyManager.setPermissionPolicy()}를 사용해 사용자에게 정상적으로 권한을 부여하라는 메시지를 표시하거나, 자동으로 권한을 허용하거나 해당 권한을 자동으로 거부하도록 할 수도 있습니다.
+
+
+ 후자의 정책이 설정된 경우, 사용자는 앱의 <strong>설정</strong> 내에 있는 권한 화면 안에서 프로필 또는 기기 소유자가 선택한 내용을 수정할 수 없습니다.
+
+</p></li>
+<li><strong>설정 VPN:</strong> 이제 VPN 앱이 <strong>설정 > 더 보기 > VPN</strong>에 표시됩니다. 이외에도, VPN 사용량에 수반되는 알림은 이제 VPN 구성 방식만 구체적으로 다루게 되었습니다.
+
+
+ 프로필 소유자의 경우, 이러한 알림은 VPN이 관리된 프로필에 대해 구성되었는지, 아니면 개인 프로필에 구성되었거나 둘 모두에 구성되었는지 여부에 한정됩니다.
+ 기기 소유자의 경우, 이 알림은 VPN이 기기 전체에 대해 구성되었는지 여부만 나타냅니다.
+</li>
+<li><strong>작업 상태 알림:</strong> 이제 관리된 프로필에서 온 앱에 전경에 있는 액티비티가 있을 때마다 상태 표시줄 서류가방 아이콘이 나타납니다.
+ 또한, 기기가 관리된 프로필 내 앱의 액티비티에 대해 직접 잠금 해제된 경우, 알림 메시지가 표시되어 사용자에게 지금 작업 프로필 내에 있다는 사실을 알려주기도 합니다.
+
+
+</li>
+</ul>
+
+<p class="note">
+ M 개발자 미리 보기의 모든 API 변경 내용에 대한 상세한 정보는 <a href="{@docRoot}preview/download.html">API 차이점 보고서</a>를 참조하세요.
+</p>
diff --git a/docs/html-intl/intl/ko/preview/behavior-changes.jd b/docs/html-intl/intl/ko/preview/behavior-changes.jd
new file mode 100644
index 0000000..fa95070
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=동작 변경
+page.keywords=미리 보기, SDK, 호환성
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">런타임 권한</a></li>
+ <li><a href="#behavior-power">절전 최적화</a>
+ <ol>
+ <li><a href="#behavior-doze">Doze</a></li>
+ <li><a href="#behavior-app-standby">앱 대기 모드</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">채택 가능한 저장소 기기</a></li>
+ <li><a href="#behavior-apache-http-client">Apache HTTP 클라이언트 제거</a></li>
+ <li><a href="#behavior-audiomanager-Changes">AudioManager 변경</a></li>
+ <li><a href="#behavior-test-selection">텍스트 선택</a></li>
+ <li><a href="#behavior-keystore">Android 키노트 변경</a></li>
+ <li><a href="#behavior-network">Wi-Fi 및 네트워킹 변경</a></li>
+ <li><a href="#behavior-camera">카메라 서비스 변경</a></li>
+ <li><a href="#behavior-art-runtime">ART 런타임</a></li>
+ <li><a href="#behavior-apk-validation">APK 유효성 검사</a></li>
+ <li><a href="#behavior-afw">Android for Work 변경</a></li>
+</ol>
+
+<h2>API 차이점</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">M 미리 보기에 대한 API 레벨 22 »</a> </li>
+</ol>
+
+
+<h2>참고 항목</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">M 개발자 미리 보기 API 개요</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M 개발자 미리 보기에는 새로운 기능 및 특징과 더불어 다양한 시스템 변경과 API 동작 변경 내용이 포함되어 있습니다.
+ 이 문서에서는 개발자 여러분이 숙지해야 하고 앱을 개발할 때 감안해야 하는 몇 가지 주요 변경 내용을 소개하겠습니다.
+</p>
+
+<p>이전에 Android용 앱을 게시한 적이 있는 경우, 이와 같은 플랫폼 변경으로 인해 앱이 영향을 받을 수 있다는 점을 유의하세요.
+</p>
+
+<h2 id="behavior-runtime-permissions">런타임 권한</h1>
+<p>이 미리 보기에서는 새 권한 모델을 소개합니다. 여기에서는 이제 사용자가 런타임에 직접 앱 권한을 관리할 수 있게 됩니다.
+ 이 모델을 사용하면 사용자에게 개선된 가시성과 권한에 대한 제어권을 부여하는 한편 앱 개발자에게는 설치와 자동 업데이트 과정을 간소화해줍니다. 사용자는 설치된 여러 앱에 대해 따로따로 권한을 허용하거나 취소할 수 있습니다.
+
+ </p>
+
+<p>M 미리 보기를 대상으로 하는 앱을 개발하는 경우, 권한 확인과 요청은 런타임에 해야 합니다.
+ 앱에 어떤 권한이 허용되었는지 판단하려면, 새로운 {@code Context.checkSelfPermission()} 메서드를 호출하면 됩니다.
+ 권한을 요청하려면 새 {@code Activity.requestPermission()} 메서드를 호출하세요.
+ 앱이 M을 대상으로 하지 않더라도, 앱을 새 권한 모델에서 테스트해보는 것이 좋습니다.
+</p>
+
+<p>앱에서 새 권한 모델을 지원하는 방법에 대한 자세한 내용은 <a href="{@docRoot}preview/features/runtime-permissions.html">권한</a> 개발자 미리 보기 페이지를 참조하세요.
+
+ 앱에 미친 영향을 평가하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">테스트 가이드</a>를 참조하세요.
+</p>
+
+<h2 id="behavior-power">절전 최적화</h2>
+<p>이 미리 보기에서는 유휴 상태의 기기 및 앱에 대한 새로운 절전 최적화 기능을 소개합니다.</p>
+
+<h3 id="behavior-doze">Doze</h3>
+<p>기기의 플러그가 뽑히고 화면이 꺼진 채로 일정 시간 동안 변화 없는 상태로 유지되면, <em>Doze</em> 상태로 들어갑니다. 이 상태에서는 기기가 시스템을 절전 모드 상태로 유지하려 시도합니다.
+ 이 모드에서 기기는 정기적으로 잠시 동안 정상 작동을 재개하여 앱 동기화가 일어날 수 있도록 하고 보류된 작업이 있으면 시스템이 이를 수행할 수 있도록 합니다.
+
+</p>
+
+<p>앱이 Doze 상태에 있는 동안 다음과 같은 제한 사항이 적용됩니다.</p>
+<ul>
+<li>네트워크 액세스가 비활성화됩니다. 다만 앱이 우선 순위가 높은 Google Cloud 메시지 Tickle을 받을 때는 예외입니다.
+</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">절전 모드 해제 잠금</a>이 무시됩니다.</li>
+<li>{@link android.app.AlarmManager} 클래스로 일정이 예약된 알람이 비활성화됩니다. 다만 {@link android.app.AlarmManager#setAlarmClock setAlarmClock()} 메서드 및 {@code AlarmManager.setAndAllowWhileIdle()}로 설정한 알람은 예외입니다.
+
+</li>
+<li>WiFi 스캔을 수행하지 않습니다.</li>
+<li>동기화 어댑터와 {@link android.app.job.JobScheduler}의 동기화와 작업 실행이 금지됩니다.
+</li>
+</ul>
+</p>
+<p>기기가 Doze 모드를 종료하면 보류되어 있던 작업과 동기화를 모두 실행합니다.</p>
+<p>이 기능을 테스트하려면 개발 머신에 M 미리 보기를 실행하는 기기를 연결하여 다음과 같은 명령을 호출하면 됩니다.
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>참고:</strong> 다가오는 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud 메시지</a> 릴리스에서는 개발자에게 우선 순위가 높은 메시지를 지정하게 해줍니다.
+
+
+ 앱이 우선 순위가 높은 GCM 메시지를 수신하면 이 앱에는 기기가 Doze 모드에 있더라도 잠시 네트워크 액세스가 허용됩니다.
+
+</p>
+
+<p>앱에서 Doze를 테스트하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#doze-standby">테스트 가이드</a>를 참조하세요.
+
+ </p>
+
+<h3 id="behavior-app-standby">앱 대기 모드</h3>
+<p>이 미리 보기에서는 시스템이 보기에 앱이 활성 사용 중이 아닌 경우 해당 앱은 유휴 상태라고 판별할 수 있습니다.
+ 일정 시간이 지나면 앱이 유휴 상태인 것으로 간주되는데, 시스템이 다음과 같은 신호 중 하나를 감지하는 경우는 예외입니다.
+</p>
+
+<ul>
+<li>사용자가 명시적으로 앱을 시작했습니다.</li>
+<li>앱에 현재 전경에 있는 프로세스가 있습니다(액티비티 또는 전경 서비스 중 하나의 형태로, 또는 다른 액티비티나 전경 서비스가 사용 중인 상태로).
+</li>
+<li>앱이 알림을 생성하여 사용자가 그것을 잠금 화면에서 보거나 알림 트레이에서 확인합니다.
+</li>
+<li><strong>설정</strong>을 통해 사용자가 명시적으로 앱이 최적화에서 면제되도록 요청합니다.
+</li>
+</ul>
+
+<p>기기의 플러그가 뽑혀 있는 경우, 유휴 상태인 것으로 간주된 앱은 자신의 네트워크 액세스를 비활성화하고 동기화와 작업을 일시 중단시킵니다.
+ 기기가 전원 공급 장치에 연결되면 이와 같은 앱에 네트워크 액세스가 허용되며 보류 중이었던 작업과 동기화를 모두 실행할 수 있습니다.
+ 기기가 오랜 시간 동안 유휴 상태인 경우, 유휴 앱에는 하루에 한 번 정도 네트워크 액세스가 허용됩니다.
+</p>
+
+<p>이 기능을 테스트하려면 개발 머신에 M 미리 보기를 실행하는 기기를 연결하여 다음과 같은 명령을 호출하면 됩니다.
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>참고:</strong> 다가오는 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud 메시지</a>(GCM) 릴리스에서는 개발자에게 우선 순위가 높은 메시지를 지정할 수 있습니다.
+
+
+ 앱이 우선 순위가 높은 GCM 메시지를 수신하면 이 앱에는 앱이 유휴 상태에 있더라도 잠시 네트워크 액세스가 허용됩니다.
+
+</p>
+
+<p>앱에서 앱 대기 모드를 테스트하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#doze-standby">테스트 가이드</a>를 참조하세요.
+
+ </p>
+
+<h2 id="behavior-adoptable-storage">채택 가능한 저장소 기기</h2>
+<p>
+이 미리 보기에서는 사용자가 SD 카드와 같은 외부 저장소 기기를 <em>채택</em>할 수 있습니다. 외부 저장소 기기를 채택하면 기기를 암호화하고 포맷하여 내부 저장소처럼 작동하도록 합니다.
+ 이 기능을 사용하면 사용자가 앱과 해당 앱의 비공개 데이터를 여러 저장소 기기 사이에서 이동시킬 수 있습니다.
+ 앱을 이동시키는 경우, 시스템은 매니페스트의 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> 기본 설정을 사용합니다.
+
+
+</p>
+
+<p>앱이 다음과 같은 API 또는 필드에 액세스하는 경우, 앱이 내부 및 외부 저장소 기기 사이를 이동하면서 반환하는 파일 경로가 급격하게 달라진다는 점을 유의하세요. 파일 경로를 구축할 때에는 이와 같은 API를 항상 동적으로 호출하는 것을 강력히 권장합니다. 하드코드된 파일 경로를 사용하거나 이전에 구축된 정규화된 파일 경로를 유지하지 마세요.
+
+
+</p>
+
+<ul>
+<li>{@link android.content.Context} 메서드:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>{@link android.content.pm.ApplicationInfo} 필드:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>개발자 미리 보기에서 이 기능을 디버그하려면, 다음 명령을 실행하여 USB On-The-Go(OTG) 케이블을 통해 Android 기기에 연결된 USB 드라이브 채택을 활성화하면 됩니다.
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Apache HTTP 클라이언트 제거</h2>
+<p>이 미리 보기에서는 Apache HTTP 클라이언트에 대한 지원을 제거합니다. 앱이 이 클라이언트를 사용하고 Android 2.3(API 레벨 9) 이상을 대상으로 하는 경우, {@link java.net.HttpURLConnection} 클래스를 대신 사용하세요.
+
+ 이는 투명한 압축과 응답 캐싱을 통해 네트워크 사용량을 줄이고 전력 소모를 최소화하기 때문에 API가 더 효율적입니다.
+ Apache HTTP API를 계속 사용하려면 우선 다음과 같은 컴파일-시간 종속성을 {@code build.gradle} 파일에서 선언해야 합니다.
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android는 OpenSSL에서 <a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> 라이브러리로 옮겨갑니다.
+
+ 앱에서 Android NDK를 사용하는 경우, NDK API의 일부분이 아닌 암호화 라이브러리에 대해 링크를 연결하지 마세요(예:{@code libcrypto.so} 및 {@code libssl.so}).
+ 이러한 라이브러리는 공개 API가 아니며, 여러 릴리스와 기기에 걸쳐 통보 없이 변경되거나 중단될 수 있으며 스스로를 보안 취약점에 노출시킬 수도 있습니다.
+
+ 대신에 원래 코드를 수정하여 JNI를 통해 Java 암호화 API를 호출하도록 하거나, 직접 선택한 암호화 라이브러리에 대해 정적으로 연결하도록 하세요.
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">AudioManager 변경</h2>
+<p>볼륨을 직접 설정하거나 특정 스트림을 {@link android.media.AudioManager} 클래스를 통해 음소거하는 것은 이제 더 이상 지원되지 않습니다.
+ {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} 메서드는 사용이 중단되었으며, 그 대신 {@code AudioManager.requestAudioFocus()} 메서드를 호출해야 합니다.
+ 이와 마찬가지로, {@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} 메서드도 사용이 중단되었습니다. 그 대신 {@code AudioManager.adjustStreamVolume()} 메서드를 호출하고 방향 값 {@code ADJUST_MUTE} 또는 {@code ADJUST_UNMUTE}에서 전달해야 합니다.
+
+
+</p>
+
+<h2 id="behavior-test-selection">텍스트 선택</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>사용자가 앱에서 텍스트를 선택하면 이제 텍스트 선택 작업을 표시할 수 있습니다. 예를 들어 <em>잘라내기</em>, <em>복사</em> 및 <em>붙여넣기</em>를 <a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">부동 도구 모음</a>으로 표시하게 됩니다.
+
+ 이 사용자 상호작용 구현은 상황별 작업 모음에서와 비슷합니다. 이 내용은 <a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">각각의 보기에 대한 상황별 작업 모드의 활성화</a>에 설명되어 있습니다.
+
+
+</p>
+
+<p>텍스트 선택을 위해 부동 도구 모음을 구현하려면 기존 앱에 다음과 같은 변경을 적용하면 됩니다.
+</p>
+<ol>
+<li>{@link android.view.View} 또는 {@link android.app.Activity} 객체에서 {@link android.view.ActionMode} 호출을 {@code startActionMode(Callback)}에서 {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}로 변경합니다.
+
+</li>
+<li>기존 {@code ActionMode.Callback} 구현을 변경하여 대신 {@code ActionMode.Callback2}를 확장합니다.
+</li>
+<li>{@code Callback2.onGetContentRect()} 메서드를 재정의하여 보기에서 콘텐츠 {@link android.graphics.Rect} 객체(예: 텍스트 선택 직사각형)의 좌표를 제공합니다.
+</li>
+<li>직사각형 위치 지정이 더 이상 유효하지 않고, 무효화할 요소가 이것뿐인 경우 {@code ActionMode.invalidateContentRect()} 메서드를 호출합니다.
+</li>
+</ol>
+
+<p><a href="{@docRoot}tools/support-library/index.html">Android 지원 라이브러리</a> 수정 버전 22.2를 사용하는 경우, 부동 도구 모음은 이전 버전과 호환되지 않으며 AppCompat이 기본적으로 {@link android.view.ActionMode} 객체의 제어권을 넘겨받는다는 점을 유의하세요.
+
+
+ 이렇게 하면 부동 도구 모음이 표시되지 않도록 방지합니다. {@link android.support.v7.app.AppCompatActivity}에서 {@link android.view.ActionMode}를 활성화하려면, {@code android.support.v7.app.AppCompatActivity.getDelegate()}를 호출한 다음 {@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()}를 반환된 {@link android.support.v7.app.AppCompatDelegate} 객체에서 호출하고 입력 매개변수를 {@code false}로 설정하세요.
+
+
+
+
+
+ 이 호출은 {@link android.view.ActionMode} 객체의 제어권을 프레임워크에 돌려줍니다.
+ M 미리 보기를 실행하는 기기에서 이렇게 하면 프레임워크가 {@link android.support.v7.app.ActionBar} 또는 부동 도구 모음 모드를 지원할 수 있고, 한편 M 미리 보기 이전 기기에서는 {@link android.support.v7.app.ActionBar} 모드만 지원됩니다.
+
+</p>
+
+<h2 id="behavior-keystore">Android 키노트 변경</h2>
+<p>이 미리 보기에서는 <a href="{@docRoot}training/articles/keystore.html">Android 키노트 제공자</a>가 더 이상 DSA를 지원하지 않습니다.
+
+ ECDSA는 여전히 지원됩니다.</p>
+
+<p>휴식 중일 때 암호화가 필요하지 않은 키도 보안 잠금 화면이 비활성화되거나 재설정될 때(예: 사용자가 또는 기기 관리자가 재설정) 더 이상 삭제되지 않습니다.
+ 휴식 중일 때 암호화가 필요한 키는 이러한 이벤트 중에 삭제됩니다.
+</p>
+
+<h2 id="behavior-network">Wi-Fi 및 네트워킹 변경</h2>
+
+<p>이 미리 보기에서는 Wi-Fi와 네트워킹 API에 다음과 같은 동작 변경을 도입합니다.</p>
+<ul>
+<li>이제 앱이 {@link android.net.wifi.WifiConfiguration} 객체의 상태를 변경할 수 있는 것은 개발자가 이와 같은 객체를 생성한 경우뿐입니다.
+ 사용자 또는 다른 앱이 생성한 {@link android.net.wifi.WifiConfiguration} 객체는 개발자가 수정하거나 삭제할 권한이 없습니다.
+
+</li>
+<li>
+이전에는 앱이 기기에 강제로 특정 Wi-Fi 네트워크에 연결하도록 하는 경우, 즉{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()}를 {@code disableAllOthers=true} 설정으로 사용하면 기기가 셀룰러 데이터와 같은 다른 네트워크에서는 연결을 해제했습니다.
+
+
+ 이 미리 보기에서는 기기가 그러한 다른 네트워크에서 더 이상 연결을 해제하지 않습니다. 앱의 {@code targetSdkVersion}이 {@code “20”} 이하인 경우, 이것은 선택한 Wi-Fi 네트워크에 고정되어 있습니다.
+
+ 앱의 {@code targetSdkVersion}이 {@code “21”} 이상인 경우, 멀티네트워크 API를 사용합니다(예: {@link android.net.Network#openConnection(java.net.URL) openConnection()}, {@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} 및 새로운 {@code ConnectivityManager.bindProcessToNetwork()} 메서드). 이렇게 하면 네트워크 트래픽이 선택한 네트워크에서 전송되도록 보장할 수 있습니다.
+
+
+
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">카메라 서비스 변경</h2>
+<p>이 미리 보기에서는 카메라 서비스에서 공유된 리소스에 액세스하는 모델이 이전의 "선착순" 액세스 모델에서 바뀌어 우선 순위가 높은 프로세스를 선호하는 액세스 모델로 변경되었습니다.
+
+ 서비스 동작에 대한 변경 내용은 다음과 같습니다.</p>
+<ul>
+<li>카메라 하위 시스템 리소스(카메라 기기 열기 및 구성하기 포함)에 대한 액세스 권한은 클라이언트 애플리케이션 프로세스의 "우선 순위"를 기반으로 부여됩니다.
+ 대개는 사용자에게 표시되는 액티비티 또는 전경 액티비티가 있는 애플리케이션 프로세스에 높은 우선 순위가 부여되어 카메라 리소스 획득과 사용에 좀 더 신뢰감을 더합니다.
+
+</li>
+<li>우선 순위가 낮은 앱에 대한 활성 카메라 클라이언트는 우선 순위가 더 높은 애플리케이션이 카메라를 사용하려 시도하면 "제거"될 수 있습니다.
+ 사용이 중단된 {@link android.hardware.Camera} API의 경우, 이 때문에 {@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}가 제거된 클라이언트에 대해 호출되는 결과를 초래합니다.
+
+
+ {@link android.hardware.camera2 Camera2} API에서는 제거된 클라이언트에 대해 {@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}가 호출됩니다.
+
+</li>
+<li>적절한 카메라 하드웨어를 갖춘 기기에서는 별도의 애플리케이션 프로세스가 각자 따로따로 열려 동시에 각기 다른 카메라 기기를 사용할 수 있습니다.
+ 하지만 여러 프로세스를 사용하는 경우 동시에 액세스하면 열려 있는 카메라 기기 모두의 성능 또는 기능이 대폭 저하되는 결과를 유발했었는데, 이런 경우도 이제 카메라 서비스가 감지하여 허용하지 않게 됩니다.
+
+ 이러한 변경으로 인해, 같은 카메라 기기에 직접 액세스하려 시도하는 앱이 없는 경우에도 우선 순위가 낮은 클라이언트를 "제거"하는 결과를 초래할 수도 있습니다.
+
+
+</li>
+<li>
+현재 사용자를 변경하면 앱 내에서 이전 사용자 계정이 소유하는 활성 카메라 클라이언트를 제거하는 결과를 유발할 수 있습니다.
+ 카메라에 대한 액세스는 현재 기기 사용자가 소유한 사용자 프로필에게만 국한됩니다. 이것은 실제로 예를 들면, 사용자가 다른 계정으로 전환하면 "Guest" 계정은 카메라 시스템을 사용하는 실행 중인 프로세스에서 나갈 수 없게 된다는 뜻입니다.
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">ART 런타임</h2>
+<p>이제 ART 런타임이 {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 메서드에 대한 액세스 규칙을 제대로 구현할 수 있습니다.
+ 이 변경 덕분에 이전 버전에서는 Dalvik이 액세스 규칙을 잘못 확인하던 문제를 해결했습니다. 앱이 {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 메서드를 사용하고 액세스 확인을 재정의하고자 하는 경우, {@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} 메서드를 호출하되 입력 매개변수를 {@code true}로 설정한 상태로 사용합니다.
+
+
+
+
+
+ 앱이 <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 AppCompat 라이브러리</a> 또는 <a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 RecyclerView 라이브러리</a>를 사용하는 경우, 앱을 업데이트하여 이러한 라이브러리의 최신 버전을 사용하도록 해야 합니다.
+
+
+ 그렇지 않으면, XML에서 참조되는 모든 사용자 지정 클래스가 업데이트되도록 확인하여 그 클래스 생성자에 액세스할 수 있도록 해야 합니다.
+</p>
+
+<p>이 미리 보기에서는 동적 링커의 동작을 업데이트합니다. 동적 링커는 이제 라이브러리의 {@code soname}과 그 경로(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">공개 버그 6670</a>) 사이의 차이점을 숙지하고 있으며, 이제 {@code soname} 기준 검색도 구현되었습니다.
+
+
+
+ 이전에 작동한 앱 중에서 {@code DT_NEEDED} 항목이 있는 경우(주로 빌드 머신의 파일 시스템에 있는 절대 경로) 로딩했을 때 실패할 수 있습니다.
+</p>
+
+<p>이제 {@code dlopen(3) RTLD_LOCAL} 플래그를 올바르게 구현했습니다. 이때 {@code RTLD_LOCAL}이 기본이므로 {@code dlopen(3)}에 대한 호출 중에서 {@code RTLD_LOCAL}을 명시적으로 사용하지 않으면 영향받을 수 있다는 점을 유의하세요(다만 앱이 명시적으로 {@code RTLD_GLOBAL}을 사용한 경우는 예외입니다).
+
+ {@code RTLD_LOCAL}의 경우, 나중에 {@code dlopen(3)}으로 한 호출로 인해 로딩된 라이브러리에서는 기호를 이용할 수 없게 됩니다({@code DT_NEEDED} 항목에 의해 참조된 것과는 반대입니다).
+
+</p>
+</p>
+
+<h2 id="behavior-apk-validation">APK 유효성 검사</h2>
+<p>이제 플랫폼이 APK에 대해 좀 더 엄격한 유효성 검사를 수행합니다. APK는 파일이 매니페스트에서는 선언되었지만 APK 자체에는 없는 경우 손상된 것으로 간주됩니다.
+ 콘텐츠가 하나라도 제거되면 APK를 다시 서명해야 합니다.
+</p>
+
+<h2 id="behavior-afw">Android for Work 변경</h2>
+<p>이 미리 보기에는 Android for Work에 대해 다음과 같은 동작 변경을 포함합니다.</p>
+<ul>
+<li><strong>업무용 연락처를 개인적인 맥락에서 이용.</strong> 이제 Google 다이얼러 통화 기록에서 사용자가 이전 통화 목록을 볼 때 업무용 연락처를 표시합니다. {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()}를 {@code true}로 설정하면 Google 다이얼러 통화 기록에서 업무용 프로필 연락처를 숨길 수 있습니다.
+
+
+ {@code DevicePolicyManager.setBluetoothContactSharingDisabled()}를 {@code false}로 설정했을 때에만 블루투스를 통해 기기에 업무용 연락처를 개인용 연락처와 함께 표시합니다.
+
+ 이것은 기본적으로 {@code true}로 설정되어 있습니다.
+
+</li>
+<li><strong>WiFi 구성 제거:</strong> 프로필 소유자가 추가한 WiFi 구성(예를 들어 {@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()} 메서드로의 호출을 통해)은 이제 해당 작업 프로필이 삭제되면 함께 제거됩니다.
+
+</li>
+<li><strong>WiFi 구성 잠금:</strong> 이제 활성 기기 소유자가 생성한 WiFi 구성이라면 사용자는 임의의 구성을 수정 또는 삭제할 수 없습니다.
+ 사용자는 여전히 본인의 WiFi 구성을 생성하고 수정할 수 있습니다. 해당 사용자에 대해 {@link android.os.UserManager} 상수 {@link android.os.UserManager#DISALLOW_CONFIG_WIFI}가 설정되지만 않았으면 됩니다.
+
+</li>
+<li><strong>Google 계정 추가를 통해 작업 정책 컨트롤러 다운로드:</strong> 작업 정책 컨트롤러(WPC) 앱을 통해 관리해야 하는 Google 계정이 관리된 맥락을 벗어나 기기에 추가되는 경우, 이제 추가 계정 흐름이 사용자에게 메시지를 표시하여 적절한 WPC를 설치하도록 합니다. 이 동작은 최초 기기 설정 마법사의 <strong>설정 > 계정</strong>을 통해서 추가되는 계정에도 적용됩니다.
+
+
+
+</li>
+<li><strong>특정 DevicePolicyManager API 동작에 적용된 변경:</strong> {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} 메서드를 호출하면 호출한 사용자에 대한 카메라에만 영향을 미칩니다. 이것을 관리된 프로필에서 호출하면 기본 사용자에서 실행 중인 카메라 앱에 영향을 미치지 않습니다.
+
+
+ 또한, 이제 {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} 메서드를 기기 소유자뿐만 아니라 프로필 소유자에 대해서도 이용할 수 있습니다.
+
+ 프로필 소유자는 다음과 같은 키가드 제한 사항을 설정할 수 있습니다.
+
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} 및 {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}를 설정하면 프로필의 상위 사용자에 대한 키가드 설정에 영향을 미칩니다.
+
+</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}를 설정하면 관리된 프로필에 있는 애플리케이션이 생성한 알림에만 영향을 미칩니다.
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..20c5232
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=권한
+page.tags=previewresources, androidm
+page.keywords=권한, 런타임, 미리 보기
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>간략히 보기</h2>
+ <ul>
+ <li>앱이 M 미리 보기 SDK를 대상으로 하는 경우, 앱은 사용자에게 설치 시점이 아닌 런타임에 권한을 허용하도록 메시지를 표시합니다.
+</li>
+ <li>사용자는 앱 설정 화면에서 언제든 권한을 취소할 수 있습니다.
+</li>
+ <li>앱은 실행될 때마다 자신에게 필요한 권한이 있는지 확인해야 합니다.
+</li>
+ </ul>
+
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#overview">개요</a></li>
+ <li><a href="#coding">런타임 권한에 대한 코딩</a></li>
+ <li><a href="#testing">런타임 권한 테스트</a></li>
+ <li><a href="#best-practices">모범 사례</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ M 개발자 미리 보기에서는 새로운 앱 권한 모델을 소개하여 사용자가 앱을 설치하고 업그레이드하는 과정을 간소화할 수 있습니다.
+ M 미리 보기에서 실행되는 앱이 새 권한 모델을 지원하는 경우, 사용자가 앱을 설치하거나 업그레이드할 때 아무런 권한을 허용하지 않아도 됩니다. 그 대신, 앱이 필요할 때마다 권한을 요청하고 시스템이 사용자에게 해당 권한을 요청하는 대화창을 표시합니다.
+
+
+
+
+</p>
+
+<p>
+ 앱이 새 권한 모델을 지원하는 경우, Android 이전 버전을 실행하는 기기에서도 설치 및 실행할 수 있는 것은 변하지 않습니다. 이 경우, 그러한 기기의 기존 권한 모델을 사용합니다.
+
+
+</p>
+
+<h2 id="overview">
+ 개요
+</h2>
+
+<p>
+ M 개발자 미리 보기에서는 플랫폼에 새로운 권한 모델을 도입합니다.
+ 이 새로운 모델의 주요 구성 요소를 다음과 같이 요약해 보았습니다.
+</p>
+
+<ul>
+ <li>
+ <strong>권한 선언:</strong> 이전 Android 플랫폼에서와 같이 앱은 자신이 필요로 하는 권한을 모두 매니페스트에서 선언합니다.
+
+ </li>
+
+ <li>
+ <strong>권한 그룹:</strong> 권한은 각자의 기능을 기반으로 <em>권한 그룹</em>으로 나뉩니다.
+ 예를 들어 <code>CONTACTS</code> 권한 그룹에는 사용자의 연락처와 프로필 정보를 읽고 쓰는 데 필요한 권한이 들어있습니다.
+
+
+ </li>
+
+ <li>
+ <p><strong>설치 시점에 제한된 권한 허용:</strong> 사용자가 앱을 설치 또는 업데이트하면 시스템이 해당 앱에 앱이 요청하는 권한 중 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}에 포함되는 것을 모두 허용합니다.
+
+
+
+ 예를 들어 알람 시계와 인터넷 권한은 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}에 속하므로 이들 권한은 설치 시점에 자동으로 허용됩니다.
+
+
+ </p>
+
+ <p>시스템은 이외에도 앱 서명과 시스템 권한을 허용할 수도 있습니다. 이 내용은 <a href="#system-apps">시스템 앱 및 서명 권한</a>에 설명되어 있습니다.
+
+ 설치 시 사용자에게 권한을 허용하라는 메시지가 표시되지 <em>않습니다.</em>
+</p>
+ </li>
+
+ <li>
+ <strong>사용자가 런타임에 권한 허용:</strong> 앱이 권한을 요청하면, 시스템이 사용자에게 대화창을 표시한 다음 앱의 콜백 기능을 호출해 권한이 허용되었는지를 알려줍니다.
+
+ 사용자가 권한을 허용하는 경우, 앱에는 앱 매니페스트에서 선언한 해당 권한의 기능 영역에 관한 모든 권한이 부여됩니다.
+
+
+ </li>
+
+</ul>
+
+<p>
+ 이 권한 모델은 앱이 권한을 필요로 하는 기능에 대해 동작하는 방식을 바꾸어 놓습니다.
+ 다음은 이 모델에 적응하기 위한 몇 가지 개발 사례를 요약했습니다.
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>항상 권한을 확인:</strong> 앱이 권한을 필요로 하는 작업을 수행해야 할 때마다, 우선 앱에 해당 권한이 있는지 확인해야 합니다.
+
+ 권한이 없는 경우, 해당 권한을 허용해도록 요청합니다.
+
+ </li>
+
+ <li>
+ <strong>권한 부족을 안정적으로 처리:</strong> 앱이 적절한 권한을 허용받지 못하면, 실패를 깔끔하게 처리할 수 있어야 합니다.
+
+ 예를 들어 권한에 기능만 추가하면 되는 것이었다면, 앱이 해당 기능을 비활성화하면 됩니다.
+ 해당 권한이 앱이 제대로 기능하는 데 꼭 필요한 것이라면, 앱이 자신의 기능을 모두 비활성화하고 사용자에게 그 권한을 허용해야 한다고 알릴 수도 있습니다.
+
+
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>그림 1.</strong> 앱의 '설정'에 있는 권한 화면.
+ </p>
+ </div>
+
+ <li>
+ <strong>취소 가능한 권한:</strong> 사용자는 언제든 앱의 권한을 취소할 수 있습니다.
+ 사용자가 앱의 권한을 끄면 해당 앱에 그 사실을 알리지 <em>않습니다.</em>
+ 이런 경우, 앱이 제한된 작업을 수행하려면 필요한 권한이 있다는 점을 다시 확인해야 합니다.
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>참고:</strong> 앱이 M 개발자 미리 보기를 대상으로 하는 경우, <em>반드시</em> 새 권한 모델을 사용해야 합니다.
+
+</p>
+
+<p>
+ M 개발자 미리 보기 시작 시점에는 Google 앱 중에 새 권한 모델을 완전히 구현하지 않는 앱도 있습니다.
+ Google은 이러한 앱을 M 개발자 미리 보기를 시행하면서 시간을 두고 업데이트하여 권한 설정/해제 설정을 제대로 사용하도록 할 예정입니다.
+
+
+</p>
+
+<p class="note">
+ <strong>참고:</strong> 앱에 자체 API 표면이 있는 경우, 권한을 대리로 허가하기 전에 우선 발신자에게 해당 데이터에 액세스할 필수 권한이 있는지 확인해야 합니다.
+
+
+</p>
+
+<h3 id="system-apps">
+ 시스템 앱 및 서명 권한
+</h3>
+
+<p>
+ 보통 사용자가 앱을 설치하면 시스템이 앱에 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}만 허용합니다.
+
+ 하지만 시스템이 앱에 더 많은 권한을 허용하는 경우도 몇 가지 있습니다.
+
+</p>
+
+<ul>
+ <li>앱이 시스템 이미지의 일부분인 경우, 이 앱의 매니페스트에 목록으로 표시된 권한을 자동으로 모두 허용합니다.
+
+ </li>
+
+ <li>앱이 매니페스트에서 권한을 요청했는데 그것이 {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE}에 속하며 해당 앱이 그러한 권한을 선언한 앱과 같은 인증서로 서명되어 있는 경우, 시스템은 요청하는 앱을 설치할 때 그러한 권한을 허용합니다.
+
+
+
+
+ </li>
+</ul>
+
+<p>
+ 두 가지 경우 모두, 사용자가 언제든 권한을 취소할 수 있는 것은 변하지 않습니다. 시스템의 <strong>설정</strong> 화면으로 이동하여 <strong>앱 ></strong>
+
+ <i>app_name</i> <strong>> 권한</strong>을 선택하면 됩니다. 이 앱은 계속해서 런타임에 권한을 확인하고 필요한 경우 해당 권한을 요청해야 합니다.
+
+
+</p>
+
+<h3 id="compatibility">
+ 이전 및 이후 버전과의 호환성
+</h3>
+
+<p>
+ 앱이 M 개발자 미리 보기를 대상으로 하지 않더라도, 앱은 M 미리 보기 기기에서도 기존 권한 모델을 계속 사용합니다.
+ 사용자가 앱을 설치하면 시스템이 사용자에게 앱의 매니페스트에 목록으로 표시된 권한을 모두 허용하도록 요청합니다.
+
+
+</p>
+
+<p class="note">
+ <strong>참고:</strong> M 개발자 미리 보기를 실행하는 기기에서는 사용자가 어느 앱에 대해서든(레거시 앱 포함) 앱의 설정 화면에서 권한을 끌 수 있습니다.
+
+ 사용자가 레거시 앱에 대한 권한을 끄면, 시스템이 자동으로 적절한 기능을 비활성화합니다.
+ 앱이 해당 권한을 필요로 하는 작업을 수행하려 시도한다고 해도 그 작업이 반드시 예외를 발생시키는 것은 아닙니다.
+
+ 그 대신에 빈 데이터 세트를 반환하거나 오류를 신호하거나, 기타 예기치 못한 동작을 선보일 수 있습니다.
+ 예를 들어 권한 없이 캘린더를 쿼리하면 해당 메서드가 빈 데이터 세트를 반환합니다.
+
+</p>
+
+<p>
+ M 미리 보기를 실행하지 않는 기기에서 새 권한 모델을 사용하는 앱을 설치하면 시스템은 해당 앱을 다른 앱과 똑같이 다룹니다. 즉, 설치 시점에 시스템에 사용자에게 선언된 권한 모두를 허용하도록 요청합니다.
+
+
+
+</p>
+
+<p class="note">
+ <strong>참고:</strong> 미리 보기 릴리스에서는 최소 SDK 버전을 M 미리 보기 SDK로 설정해야 미리 보기 SDK와 컴파일할 수 있습니다.
+ 즉, 개발자 미리 보기 시행 중에는 그러한 앱을 기존 플랫폼에서 테스트할 수 없다는 뜻입니다.
+
+
+</p>
+
+<h3 id="perms-vs-intents">권한과 인텐트 비교</h3>
+
+<p>
+ 대부분의 경우, 앱에게 어떤 작업을 수행하도록 하려면 두 가지 방식 중 하나를 선택할 수 있습니다.
+ 첫째로 앱이 작업을 직접 수행하도록 권한을 요청할 수 있습니다.
+ 또는, 앱에 인텐트를 사용하도록 하여 또 다른 앱이 해당 작업을 수행하도록 할 수 있습니다.
+
+</p>
+
+<p>
+ 예를 들어 앱이 기기 카메라로 사진을 촬영할 수 있어야 한다고 가정합시다.
+ 그러면 앱은 <code>android.permission.CAMERA</code> 권한을 요청할 수 있습니다. 이렇게 하면 앱이 카메라에 직접 액세스할 수 있습니다.
+
+ 그런 다음 앱이 카메라 API를 사용하여 카메라를 제어하고 사진을 촬영합니다.
+ 이 방식을 사용하면 앱에 사진 촬영 과정에 대해 완전한 제어권을 부여하고, 카메라 UI를 앱에 통합할 수 있습니다.
+
+
+</p>
+
+<p>
+ 하지만, 그러한 제어권이 필요하지 않은 경우라면 그저 {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} 인텐트를 사용해 이미지를 요청하면 됩니다.
+
+ 이 인텐트를 시작하면 사용자에게 카메라 앱을 선택하라는 메시지가 표시되고(기본 카메라 앱이 이미 있는 경우) 그 앱이 사진을 촬영합니다.
+
+ 이 카메라 앱은 촬영한 사진을 개발자의 앱의 {@link android.app.Activity#onActivityResult onActivityResult()} 메서드에 반환합니다.
+
+</p>
+
+<p>
+ 이와 마찬가지로, 전화를 걸어야 하거나 사용자의 연락처에 액세스해야 하는 경우 등에는 적절한 인텐트를 만들거나 적절한 객체에 직접 액세스하도록 권한을 요청할 수 있습니다.
+
+ 이 두 가지 방식에는 각각 장단점이 있습니다.
+
+</p>
+
+<p>
+ 권한을 사용하는 경우:
+</p>
+
+<ul>
+ <li>개발자가 직접 작업을 수행하는 경우 본인의 앱이 사용자 환경을 완전히 제어합니다.
+ 다만, 그렇게 포괄적인 제어권을 가지면 적절한 UI를 디자인해야 하므로 작업이 복잡해집니다.
+
+ </li>
+
+ <li>사용자에게 권한을 부여하라는 메시지는 작업을 처음 수행할 때만 표시됩니다.
+ 그 다음부터는 앱이 사용자로부터 더 이상의 상호작용을 요청하지 않아도 작업을 수행할 수 있습니다.
+ 다만, 사용자가 해당 권한을 허용하지 않는 경우(또는 나중에 취소하는 경우), 앱은 해당 작업을 수행할 수 없게 됩니다.
+
+
+ </li>
+</ul>
+
+<p>
+ 인텐트를 사용하는 경우:
+</p>
+
+<ul>
+ <li>작업을 위해 UI를 디자인하지 않아도 됩니다. 이는 인텐트를 처리하는 앱이 UI를 제공하기 때문입니다. 하지만, 이것은 즉 개발자에게 사용자 환경에 대한 제어권이 전혀 없다는 뜻이기도 합니다.
+
+ 사용자는 어쩌면 개발자가 본 적도 없는 앱과 상호작용하고 있을지 모릅니다.
+
+ </li>
+
+ <li>사용자에게 해당 작업에 대한 기본 앱이 없는 경우, 시스템은 사용자에게 앱을 선택하라는 메시지를 표시합니다. 사용자가 기본 처리기를 지정하지 않으면 해당 작업을 수행할 때마다 추가 대화창을 거쳐야 할 수도 있습니다.
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">런타임 권한에 대한 코딩</h2>
+
+<p>
+ 새로운 M 개발자 미리 보기를 대상으로 앱을 개발하는 경우, 새 권한 모델을 사용해야 합니다.
+ 이는 즉, 매니페스트에 필요한 권한을 선언하는 것 말고도 런타임에 자신이 해당 권한을 가지고 있는지도 확인해야 하며, 그러한 권한을 이미 가지고 있지 않으면 권한을 요청해야 한다는 뜻입니다.
+
+
+
+</p>
+
+<h3 id="enabling">
+ 새 권한 모델 활성화하기
+</h3>
+
+<p>
+ 새로운 M 개발자 미리 보기 권한 모델을 활성화하려면 앱의 <code>targetSdkVersion</code> 특성을 <code>"MNC"</code>로 설정하고, <code>compileSdkVersion</code>은 <code>"android-MNC"</code>로 설정하세요.
+
+ 이렇게 하면 새 권한 기능이 모두 활성화됩니다.
+
+</p>
+
+<p>
+ 미리 보기 릴리스에서는 <code>minSdkVersion</code>을 <code>"MNC"</code>로 설정해야만 미리 보기 SDK와 컴파일할 수 있습니다.
+
+</p>
+
+<h3 id="m-only-perm">
+ M 미리 보기 전용 권한 지정하기
+</h3>
+
+<p>
+ 새 <code><uses-permission-sdk-m></code> 요소를 앱 매니페스트에 사용하여 권한이 M 개발자 미리 보기에서만 필요하다는 것을 나타낼 수 있습니다.
+ 권한을 이런 식으로 선언하면 앱이 이전 버전의 기기에 설치될 때마다 시스템에서 사용자에게 메시지를 표시하지도 않고 앱에 권한을 허용하지도 않습니다. <code><uses-permission-sdk-m></code> 요소를 사용하면 새 권한을 앱의 업데이트된 버전에 추가하면서도 사용자가 업데이트를 설치할 때 권한을 허용하라고 강제로 시키지 않아도 됩니다.
+
+
+
+
+
+
+</p>
+
+<p>
+ 앱이 M 개발자 미리 보기를 갖춘 기기에서 실행되는 경우, <code><uses-permission-sdk-m></code>은 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>과 똑같이 동작합니다.
+
+
+ 시스템은 사용자가 앱을 설치할 때 권한을 허용하라는 메시지를 표시하지 않고, 앱이 필요할 때마다 권한을 요청하게 됩니다.
+
+</p>
+
+<h3 id="prompting">
+ 권한에 대한 메시지 표시하기
+</h3>
+
+<p>
+ 앱이 새로운 M 개발자 미리 보기 권한 모델을 사용하는 경우, 앱이 M 미리 보기에서 실행되는 기기에서 처음 시작되었을 때 사용자에게 모든 권한을 허용하도록 요청하지 않습니다.
+
+ 대신, 앱은 필요할 때마다 권한을 요청합니다.
+ 앱이 권한을 요청하면 시스템이 사용자에게 대화창으로 표시합니다.
+
+</p>
+
+<p>
+ 앱이 SDK 22 이하를 탑재한 기기에서 실행되는 경우, 앱은 기존 권한 모델을 사용합니다.
+ 사용자가 앱을 설치하면 앱이 자신의 매니페스트에서 요청하는 모든 권한을 허용하라는 메시지가 표시되는데, 이때 <code><uses-permission-sdk-m></code>이라는 레이블이 붙은 권한은 예외입니다.
+
+
+</p>
+
+<h4 id="check-platform">앱이 실행되는 플랫폼 확인</h4>
+
+<p>
+ 이 권한 모델은 M 개발자 미리 보기를 실행하는 기기에서만 지원됩니다.
+ 이러한 메서드 중에서 호출하려면 앱은 우선 {@link android.os.Build.VERSION#CODENAME Build.VERSION.CODENAME} 값을 확인하여 자신이 어느 플랫폼에서 실행 중인지 확인해야 합니다.
+
+
+ 기기가 M 개발자 미리 보기에서 실행 중인 경우, {@link android.os.Build.VERSION#CODENAME CODENAME}은 <code>"MNC"</code>입니다.
+
+</p>
+
+<h4 id="check-for-permission">앱에 필요한 권한이 있는지 확인</h4>
+
+<p>사용자가 권한을 필요로 하는 무언가를 하려고 시도하면, 앱은 자신이 현재 이 작업을 수행하는 데 필요한 권한을 가지고 있는지 확인합니다.
+ 이렇게 하기 위해 앱은 <code>Context.checkSelfPermission( )</code>을 호출합니다.
+
+<i>permission_name</i> 사용자가 앱의 권한을 언제든 취소할 수 있기 때문에 앱은 사용자가 해당 권한을 이미 허용했다는 것을 알고 있더라도 확인 작업을 수행해야 합니다.
+
+
+ 예를 들어, 사용자가 사진 촬영 앱을 사용하고자 한다면 앱은 <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>를 호출합니다.
+
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>표 1.</strong> 권한과 권한 그룹.</p>
+<table>
+ <tr>
+ <th scope="col">권한 그룹</th>
+ <th scope="col">권한</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">필요한 경우 권한 요청</h4>
+
+<p>앱이 자신에게 필요한 권한을 이미 가지고 있지 않은 경우, 앱은 <code>Activity.requestPermissions(String[], int)</code> 메서드를 호출하여 적절한 권한(여러 개일 수 있음)을 요청합니다.
+
+ 앱은 원하는 권한을 요청하면서 정수 "요청 코드"를 요청합니다.
+
+ 이 메서드는 비동기화 방식으로 기능합니다. 이는 즉각적으로 반환되며, 사용자가 대화 상자에 응답한 다음에는 시스템이 결과를 가지고 앱의 콜백 메서드를 호출하여 앱이 <code>requestPermissions()</code>에 전달한 "요청 코드"와 같은 코드를 전달합니다.
+
+
+</p>
+
+ <p>다음 코드는 앱에 사용자의 연락처를 읽을 권한이 있는지 코드 확인을 하고, 필요한 경우 해당 권한을 요청합니다.
+</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">권한 요청 응답 처리하기</h4>
+
+<p>
+ 앱이 권한을 요청하면 시스템이 사용자에게 대화 상자를 표시합니다.
+ 사용자가 응답하면 시스템은 앱의 <code>Activity.onRequestPermissionsResult(int, String[], int[])</code>를 불러내 이를 사용자 응답에 전달합니다.
+
+ 앱은 해당 메서드를 재정의해야 합니다. 이 콜백에는 개발자가 <code>requestPermissions()</code>에 전달한 것과 같은 요청 코드가 전달됩니다.
+
+ 예를 들어 어느 앱이 <code>READ_CONTACTS</code> 액세스를 요청한다면 다음과 같은 콜백 메서드를 가지고 있을 수 있습니다.
+
+
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>사용자가 권한을 허용하면 시스템은 앱 매니페스트에 그 기능 영역에 대해 목록으로 표시된 모든 권한을 해당 앱에 부여합니다.
+ 사용자가 요청을 거부하면 적절한 조치를 취해야 합니다.
+ 예를 들어 이 권한에 좌우되는 메뉴 작업을 모두 비활성화할 수 있습니다.
+
+ </li>
+</p>
+
+<p>
+ 시스템이 사용자에게 권한을 허용하도록 요청하면 사용자에게는 시스템에 해당 권한을 다시 요청하지 말라고 지시할 선택권이 있습니다.
+ 그런 경우, 앱이 해당 권한을 요청하기 위해 <code>requestPermissions()</code>를 사용하면 시스템이 즉시 요청을 거부합니다.
+
+ 이 경우 시스템은 사용자가 명시적으로 개발자의 요청을 다시 거부한 것처럼 <code>onRequestPermissionsResult()</code>를 호출합니다.
+
+ 이러한 이유로, 앱은 사용자와의 직접적인 상호작용이 일어났다고 가정해서는 안 됩니다.
+
+</p>
+
+<h2 id="testing">런타임 권한 테스트</h2>
+
+
+<p>
+ M 개발자 미리 보기를 대상으로 삼고 앱을 개발하는 경우, 이 앱이 권한을 적절하게 처리하는지 테스트해보아야 합니다.
+ 앱이 실행될 때 특정 권한을 가지고 있다고 가정해서는 안 됩니다.
+ 앱을 처음 시작할 때에는 아무런 권한도 없을 가능성이 높고, 사용자가 언제든 권한을 취소하거나 복원할 수 있기 때문입니다.
+
+
+</p>
+
+<p>
+ 앱을 테스트하여 모든 권한 관련 상황에서 제대로 작동하는지 확인하는 것이 좋습니다.
+ M 미리 보기 SDK에서는 새로운 <a href="{@docRoot}tools/help/adb.html">Android 디버그 브리지(adb)</a> 명령을 제공하여 여러분이 시도해 보아야 하는 권한 설정이 무엇이든 앱을 테스트할 수 있도록 하였습니다.
+
+
+
+</p>
+
+<h3>
+ 새로운 adb 명령 및 선택 사항
+</h3>
+
+<p>
+ M 미리 보기 SDK 플랫폼 도구에서는 여러 가지 새로운 명령을 제공하여 앱이 권한을 처리하는 방식을 테스트해볼 수 있습니다.
+
+</p>
+
+<h4>
+ 권한으로 설치
+</h4>
+
+<p>
+ <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a> 명령의 새로운 <code>-g</code> 선택 항목을 사용하면 앱을 설치하고 해당 앱의 매니페스트에 목록으로 표시된 모든 권한을 허용합니다.
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ 권한 허용 및 취소
+</h4>
+
+<p>
+ 새로운 ADB <a href="{@docRoot}tools/help/adb.html#pm">패키지 관리자(pm)</a> 명령을 사용하면 설치된 앱에 권한을 허용하고 취소할 수 있습니다. 이 기능은 자동화 설정에서 유용하게 쓰일 수 있습니다.
+
+
+</p>
+
+<p>
+ 권한을 허용하려면, 패키지 관리자의 <code>grant</code> 명령을 사용하세요.
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ 예를 들어 com.example.myapp 패키지 권한을 허용하여 오디오를 녹음하려면 이 명령을 사용하면 됩니다.
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ 권한을 취소하려면, 패키지 관리자의 <code>revoke</code> 명령을 사용하세요.
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">모범 사례</h2>
+
+<p>
+ 새 권한 모델을 사용하면 사용자에게 보다 원활한 환경을 제공하고, 앱을 더욱 쉽게 설치하며 앱이 어떤 작업을 하고 있는지 바로 확인할 수 있습니다.
+
+ 새 모델의 장점을 최대한 활용할 수 있도록 다음과 같은 모범 사례를 추천해 드립니다.
+
+</p>
+
+
+<h3 id="bp-what-you-need">필요한 권한만 요청</h3>
+
+<p>
+ 권한을 요청할 때마다 사용자에게는 결정을 내리라는 강요를 하는 셈입니다.
+ 사용자가 요청을 거절하면 앱의 기능이 저하됩니다.
+ 때문에 이러한 요청을 하는 횟수를 최소한으로 줄이는 것이 좋습니다.
+</p>
+
+<p>
+ 예를 들어 앱이 권한을 요청하는 대신 <a href="{@docRoot}guide/components/intents-filters.html">인텐트</a>를 사용해 필요한 기능을 얻을 수 있는 경우도 꽤 많습니다.
+
+ 앱이 전화기의 카메라를 사용해 사진을 촬영해야 하는 경우, 앱은 {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} 인텐트를 사용할 수 있습니다.
+
+
+ 앱이 인텐트를 실행하면 시스템이 사용자에게 메시지를 표시해 이미 설치된 카메라 앱을 선택하여 사진을 촬영하도록 합니다.
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ 사용자에게 부담을 주지 말 것
+</h3>
+
+<p>
+ 사용자에게 엄청나게 많은 수의 권한 요청을 한꺼번에 들이밀면 사용자가 부담을 느끼고 앱을 종료해버리는 결과를 초래할 수 있습니다. 대신 권한이 필요할 때마다 요청하는 것이 좋습니다.
+
+
+</p>
+
+<p>
+ 일부 경우에는 앱에 절대적으로 꼭 필요한 권한이 한 개 이상 있을 수도 있습니다. 그런 경우에는 앱이 시작되자마자 해당 권한을 모두 요청하는 것을 권장합니다.
+
+ 예를 들어 사진 앱을 만들면 앱이 기기 카메라로 액세스할 수 있는 권한이 필요합니다.
+ 사용자가 앱을 처음으로 시작할 때 카메라를 사용할 권한을 요청받아도 놀라지는 않을 것입니다.
+
+ 하지만 같은 앱에 사용자의 연락처과 사진을 공유하는 기능도 있다고 가정한다면 이 경우 해당 권한을 첫 시작 시점에 요청하는 것은 별로 권장할 만한 일이 <em>아닙니다.</em>
+
+ 대신, 사용자가 "공유" 기능을 요청하려 할 때까지 기다렸다가 그 때 해당 권한을 요청하면 됩니다.
+
+</p>
+
+<p>
+ 앱이 튜토리얼을 제공하는 경우, 튜토리얼 시퀀스가 다 끝날 무렵에 앱의 필수 권한을 요청하는 것이 이치에 맞을 수 있습니다.
+
+</p>
+
+<h3 id="bp-explain">
+ 권한이 필요한 이유 설명
+</h3>
+
+<p>
+ 개발자가 <code>requestPermissions()</code>를 호출하면 시스템이 표시하는 권한 대화창에는 앱이 원하는 권한이 무엇인지는 나타나 있지만 그것이 필요한 이유는 설명하지 않습니다.
+
+ 사용자가 이런 것을 의아하게 여기는 경우가 있을 수 있습니다.
+ 우선 사용자에게 앱이 왜 그런 권한을 원하는지 설명한 다음 <code>requestPermissions()</code>를 호출하는 것이 좋습니다.
+
+</p>
+
+<p>
+ 예를 들어 사진 앱인 경우 위치 서비스를 이용하고자 할 수 있습니다. 그래야 사진에 지오태그를 표시할 수 있기 때문입니다.
+ 일반적인 사용자는 사진에 위치 정보를 담을 수 있다는 점을 모를 수도 있고, 그러면 사진 앱이 왜 위치를 알고 싶어 하는지 의아하게 여길 수 있습니다.
+
+ 그러므로 이런 경우에는 앱이 사용자에게 이런 기능에 대해 <em>미리</em> 알려드린 후 <code>requestPermissions()</code>를 호출하는 것이 좋습니다.
+
+
+</p>
+
+<p>
+ 이를 수행하기 위한 한 가지 방법은 이러한 요청을 앱 튜토리얼에 넣는 것입니다. 튜토리얼에는 앱의 각 기능을 표시할 수 있고, 그러면서 어느 권한이 필요한지 설명할 수도 있기 때문입니다.
+
+ 예를 들어 사진 앱의 튜토리얼에서 "연락처 목록의 지인들과 사진 공유" 기능을 시연한 다음 사용자에게 앱이 사용자의 연락처를 보려면 권한을 부여해야 한다고 알리면 됩니다.
+
+
+ 그런 다음, 앱이 <code>requestPermissions()</code>를 호출하여 사용자에게 해당 액세스를 요청합니다.
+ 물론 튜토리얼을 따르지 않는 사용자도 있게 마련이므로 앱의 정상 작동 중에 권한을 확인하고 요청해야 합니다.
+
+
+</p>
diff --git a/docs/html-intl/intl/ko/preview/overview.jd b/docs/html-intl/intl/ko/preview/overview.jd
new file mode 100644
index 0000000..d325725
--- /dev/null
+++ b/docs/html-intl/intl/ko/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=프로그램 개요
+page.metaDescription=Android M 개발자 미리 보기를 시작하신 여러분, 환영합니다. 이 프로그램은 Android의 다음 버전에 대해 앱을 테스트하고 최적화하는 데 필요한 모든 것을 제공해 드립니다.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ <strong>Android M 개발자 미리 보기</strong>를 시작하신 여러분, 환영합니다. 이 프로그램은 Android의 다음 버전에 대해 앱을 테스트하고 최적화하는 데 필요한 모든 것을 제공해 드립니다.
+
+ 이 프로그램은 무료이며, M 개발자 미리 보기 도구만 다운로드하면 시작하실 수 있습니다.
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ 하드웨어 및 에뮬레이터 시스템 이미지
+ </h5>
+
+ <p>
+ Nexus 5, 6, 9, Player(TV용)와 에뮬레이터에서 앱을 실행하고 테스트해 보세요.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 최신 플랫폼 코드
+ </h5>
+
+ <p>
+ 미리 보기 시행 중에 여러 번의 업데이트를 제공할 예정입니다. 이로써 여러분은 항상 최신 플랫폼 변경에 대해 테스트할 수 있습니다.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 업데이트를 OTA로 전달
+ </h5>
+
+ <p>
+ 일단 기기를 최초 미리 보기에 플래시하고 나면 OTA로 업데이트를 받을 수 있습니다.
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 새 동작 및 기능
+ </h5>
+
+ <p>
+ 작업을 일찍 시작하여 새 런타임 권한 모델과 절전 기능 등 새로운 플랫폼 동작을 지원합니다.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 개발자가 보고한 문제에 대한 우선 순위 창
+ </h5>
+
+ <p>
+ Google에서는 처음 몇 주 동안 개발자가 보고한 문제에 우선 순위를 부여할 예정입니다. 가능한 빨리 테스트하고 피드백을 보내 주세요.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 피드백 및 지원
+ </h5>
+
+ <p>
+ 문제를 보고하고 Google의 <a href="https://code.google.com/p/android-developer-preview/">문제 추적기</a>를 사용해 피드백을 보내 주세요.
+ <a href="http://g.co/dev/AndroidMDevPreview">M 개발자 커뮤니티</a>를 이용하면 다른 개발자들과 의견을 주고받을 수 있습니다.
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ 일정 및 업데이트
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M 개발자 미리 보기는 5월 28일부터 최종 Android M SDK가 출시될 때까지 실행됩니다. 최종 버전은 2015년 3사분기 중으로 예정된 공개 릴리스 직전에 출시할 계획입니다.
+
+
+</p>
+
+<p>
+ 개발 중 중요 단계에 다다를 때마다 여러분의 테스트 기기를 위해 업데이트를 전달해 드리겠습니다.
+ 잠정적인 중요 단계는 다음과 같습니다.
+</p>
+
+<ul>
+ <li>
+ <strong>미리 보기 1</strong>(최초 미리 보기 릴리스, 5월 말)
+ </li>
+
+ <li>
+ <strong>미리 보기 2</strong>(6월 말/7월 초)
+ </li>
+
+ <li>
+ <strong>미리 보기 3</strong>(최종 버전 출시 직전, 7월 말)
+ </li>
+</ul>
+
+<p>
+ 이러한 업데이트는 <strong>최종 SDK</strong>(3사분기 후반)로 막을 내릴 것이며, 이것으로 Android 새 버전에 대한 공식 API뿐만 아니라 최종 시스템 동작 및 기능도 제공하게 됩니다.
+
+
+</p>
+
+<p>
+ Android M에서 테스트와 개발을 수행하는 동안 미리 보기 업데이트가 출시되는 것에 맞춰 <strong>개발 환경을 최신 상태로 유지</strong>할 것을 강력히 권장합니다.
+
+ 이 과정을 보다 단순화하기 위해 이미 미리 보기 빌드에 플래시한 기기에는 <strong>OTA(over-the-air) 업데이트</strong>를 제공할 예정이며, 이외에도 수동으로 다운로드하고 플래시할 수 있는 시스템 이미지도 제공할 계획입니다.
+
+
+</p>
+<p class="note">
+ <strong>참고:</strong> 최종 SDK와 시스템 이미지는 OTA로 전달할 수 없습니다. 그 대신 개발자 본인의 테스트 기기에서 <strong>수동으로 플래시</strong>해야 합니다.</strong>
+
+
+</p>
+
+<p>
+ 미리 보기 업데이트를 이용할 수 있게 될 때마다 <a href="http://android-developers.blogspot.com/">Android 개발자 블로그</a>, 해당 사이트 및 <a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>를 통해서 알려드릴 것입니다.
+
+
+</p>
+
+<h2 id="preview_tools">
+ 미리 보기 내용
+</h2>
+
+<p>
+ M 개발자 미리 보기에는 기존 앱을 여러 가지 화면 크기, 네트워크 기술, CPU/GPU 칩세트 및 하드웨어 아키텍처에서 테스트하는 데 필요한 모든 것이 포함되어 있습니다.
+
+
+</p>
+
+<h4>
+ SDK 도구
+</h4>
+
+<p>
+ 이러한 구성 요소는 <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>에서 SDK Manager를 통해 다운로드할 수 있습니다.
+</p>
+
+<ul>
+ <li>M 개발자 미리 보기 <strong>SDK 도구</strong>
+ </li>
+
+ <li>M 개발자 미리 보기 <strong>에뮬레이터 시스템 이미지</strong>(32비트 및 64비트)
+
+ </li>
+
+ <li>M 개발자 미리 보기 <strong>Android TV용 에뮬레이터 시스템 이미지</strong>(32비트)
+
+ </li>
+</ul>
+
+<h4>
+ 하드웨어 시스템 이미지
+</h4>
+
+<p>
+ Nexus 기기에 대한 다음과 같은 하드웨어 시스템 이미지는 <a href="download.html">다운로드 페이지</a>에서 다운로드할 수 있습니다.
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong>(GSM/LTE) “hammerhead” 기기 시스템 이미지
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> “shamu” 기기 시스템 이미지
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong>(Wi-Fi) “volantis” 기기 시스템 이미지
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong>(Android TV) “fugu” 기기 시스템 이미지
+ </li>
+</ul>
+
+<h4>
+ 관련 문서 및 샘플 코드
+</h4>
+
+<p>
+ 다음과 같은 관련 문서 리소스는 미리 보기에 대해 익히는 데 유용합니다.
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">SDK 설정</a>에는 시작하는 데 필요한 단계별 지침이 들어 있습니다.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">테스트 가이드</a>와 <a href="behavior-changes.html">동작 변경</a>에서는 테스트해야 할 주요 영역을 알려줍니다.
+ </li>
+
+ <li>새 API 관련 문서 중에서 <a href="api-overview.html">API 개요</a>, 다운로드할 수 있는 <a href="{@docRoot}preview/download.html#docs">API 참조</a>와 자세한 개발자 가이드(<a href="{@docRoot}preview/features/runtime-permissions.html">권한</a>, <a href="{@docRoot}preview/backup/index.html">앱 백업</a> 등 주요 기능에 대한 내용)도 참조하세요.
+
+
+
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">샘플 코드</a>는 권한과 기타 새로운 기능을 지원하는 방법을 설명합니다.
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">릴리스 노트</a>를 보면 M 개발자 미리 보기의 현재 버전에 대해 변경 내용 참고 사항과 차이점 보고서 등 관련 정보를 확인할 수 있습니다.
+
+ </li>
+</ul>
+
+<h4>
+ 지원 리소스
+</h4>
+
+<p>
+ M 개발자 미리 보기에서 테스트하고 개발하는 데 유용한 지원 리소스를 소개합니다.
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">M 개발자 미리 보기 문제 추적기</a>가 여러분의 <strong>기본 피드백 채널</strong>입니다.
+
+ 문제 추적기를 통해 버그와 성능 문제를 보고하고 전반적인 피드백을 주시면 됩니다.
+ 이를 통해 <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">알려진 문제</a>를 확인하고 해결 방법 단계를 찾아볼 수도 있습니다.
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>는 일종의 Google+ 커뮤니티로, 여기에서 여러분은 Android M을 가지고 작업하는 <strong>다른 개발자들과 이야기</strong>를 나눌 수 있습니다. 서로의 의견이나 아이디어를 나누고 Android M 관련 질문에 대한 대답을 찾을 수도 있습니다.
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 대상 지정, 미리 보기 API 및 게시
+</h2>
+
+<p>
+ Android M 개발자 미리 보기는 개발 전용 릴리스이며 <strong>표준 API 레벨이 없습니다</strong>.
+ 앱을 테스트하기 위해 호환성 동작에서 옵트아웃하고자 하는 경우(강력히 권장함), M 개발자 미리 보기를 대상으로 지정하면 됩니다. 앱의 <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>을 <code>“MNC”</code>로 지정하세요.
+
+
+
+</p>
+
+<p>
+ Android M 개발자 미리 보기에서는 <strong>미리 보기 API</strong>를 제공합니다. —이 API는 최종 SDK가 출시될 때까지 공식적인 버전으로 인정되지 않습니다. 최종 SDK 릴리스는 현재 2015년 삼사분기 무렵으로 예정되어 있습니다.
+
+ 이는 즉, 시간이 지나면서 <strong>사소한 API 변경</strong>이 있을 것이라는 점을 예상해야 한다는 뜻입니다. 특히 프로그램 초반 몇 주 동안은 유의해야 합니다.
+
+ Android M 개발자 미리 보기를 업데이트할 때마다 변경 내용을 요약해서 제공해 드릴 것입니다.
+
+</p>
+
+<p class="note">
+ 미리 보기 API는 변경될 수 있지만, 런타임 권한과 절전 기능과 같은 기본 시스템 동작은 안정적이며 지금 바로 테스트 가능한 상태입니다.
+
+
+</p>
+
+<p>
+ 게시에 관해서는, Google Play에서는 <strong>M 개발자 미리 보기를 대상으로 삼는 앱의 게시를 방지합니다.</strong>
+ Android M 최종 SDK를 이용할 수 있게 되면 공식 Android M API 레벨을 대상으로 지정할 수 있고, 그때 Google Play에 앱을 게시하면 됩니다.
+
+ 그때까지는 테스터들에게 Android M을 대상으로 지정한 앱을 배포하고자 하는 경우 이메일이나 본인의 사이트에서 직접 다운로드를 통해 하시면 됩니다.
+
+
+</p>
+
+<h2 id="get_started">
+ 시작 방법
+</h2>
+
+<p>
+ 앱 테스트를 시작하려면
+</p>
+
+<ol>
+ <li><a href="{@docRoot}preview/api-overview.html">API 개요</a>와 <a href="{@docRoot}preview/behavior-changes.html">동작 변경</a>을 검토해 새로운 내용과 이것이 본인의 앱에 미치는 영향에 대해 알고 있어야 합니다.
+
+ 특히, 새로운 <a href="{@docRoot}preview/features/runtime-permissions.html">런타임 권한</a> 모델, 절전 기능과 자동 백업에 대해 숙지하는 것이 좋습니다.
+
+
+ </li>
+
+ <li>환경을 설정할 때에는 <a href="{@docRoot}preview/setup-sdk.html">미리 보기 SDK 설정</a>과 테스트 기기를 구성하는 데 관련된 지침을 따르세요.
+
+
+ </li>
+
+ <li><a href="https://developers.google.com/android/nexus/images">플래시 지침</a>을 따라 최신 M 개발자 미리 보기 시스템 이미지를 Nexus 5, 6, 9 및 Player에 플래시하세요.
+
+ 일단 개발 기기를 플래시하고 나면, 미리 보기 업데이트가 OTA(over-the-air) 업데이트를 통해 전달됩니다.</a>
+
+ </li>
+
+ <li><a href="{@docRoot}preview/download.html#docs">M 미리 보기 API 참조</a>와 <a href="{@docRoot}preview/samples.html">M 미리 보기 샘플</a>을 다운로드하면 새로운 API 기능과 앱에서 그러한 기능을 사용하는 방법에 대해 좀 더 자세히 파악할 수 있습니다.
+
+
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>에 가입하여 최신 소식을 알아보고, 새 플랫폼으로 작업하는 다른 개발자들과 이야기를 나눠보세요.
+
+
+ </li>
+</ol>
+
+<p>
+ Android M 개발자 미리 보기 프로그램에 참가해 주셔서 대단히 감사합니다!
+</p>
diff --git a/docs/html-intl/intl/pt-br/preview/api-overview.jd b/docs/html-intl/intl/pt-br/preview/api-overview.jd
new file mode 100644
index 0000000..33e8c1f
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=Visão geral da API
+page.keywords=preview,sdk,compatibility
+page.tags=previewresources, androidm
+sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Neste documento
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">mostrar mais</span>
+ <span class="less" style="display:none">mostrar menos</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">Vínculo de aplicativo</a></li>
+ <li><a href="#backup">Backup automático para aplicativos</a></li>
+ <li><a href="#authentication">Autenticação</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">Autenticação com impressão digital</a></li>
+ <li><a href="#confirm-credential">Confirmação de credencial</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">Compartilhamento direto</a></li>
+ <li><a href="#voice-interactions">Interações por voz</a></li>
+ <li><a href="#assist">Auxiliar API</a></li>
+ <li><a href="#notifications">Notificações</a></li>
+ <li><a href="#bluetooth-stylus">Suporte para Bluetooth Stylus</a></li>
+ <li><a href="#ble-scanning">Digitalização de baixa energia por Bluetooth aprimorada</a></li>
+ <li><a href="#hotspot">Suporte a Hotspot 2.0 Release 1</a></li>
+ <li><a href="#4K-display">Modo de exibição 4K</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">ColorStateLists com tema</a></li>
+ <li><a href="#audio">Recursos de áudio</a></li>
+ <li><a href="#video">Recursos de vídeo</a></li>
+ <li><a href="#camera">Recursos de câmera</a>
+ <ol>
+ <li><a href="#flashlight">API da lanterna</a></li>
+ <li><a href="#reprocessing">Reprocessamento da câmera</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Recursos do Android for Work</a></li>
+</ol>
+
+<h2>Diferenças de API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API de nível 22 para M Preview »</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>O M Developer Preview fornece uma visualização avançada no próximo lançamento
+ para a plataforma Android, oferecendo novos recursos para desenvolvedores e usuários
+de aplicativos. Este documento fornece uma introdução às APIs mais notáveis.</p>
+
+<p>O M Developer Preview foi feito para <strong>novos desenvolvedores
+adotantes</strong> e <strong>testadores</strong>. Caso tenha interesse
+ em influenciar a direção da estrutura do Android,
+<a href="{@docRoot}preview/setup-sdk.html">experimente o M Developer
+ Preview</a> e envie-nos feedback!</p>
+
+<p class="caution"><strong>Cuidado:</strong> não publique aplicativos
+que usam o M Developer Preview na Google Play Store.</p>
+
+<p class="note"><strong>Observação:</strong> este documento frequentemente
+menciona classes e métodos que ainda não possuem material de referência disponível em <a href="{@docRoot}">developer.android.com</a>. Esses elementos de API
+são formatados em {@code code style} neste documento (sem hyperlinks). Para a
+documentação de API preliminar destes elementos, faça o download da <a href="{@docRoot}preview/download.html#docs">referência da prévia</a>.</p>
+
+<h3>Alterações importantes de comportamento</h3>
+
+<p>Caso tenha publicado anteriormente um aplicativo para Android, saiba que ele pode ser afetado
+pelas alterações na plataforma.</p>
+
+<p>Consulte <a href="behavior-changes.html">alterações de comportamento</a> para obter mais informações.</p>
+
+<h2 id="app-linking">Vínculo de aplicativo</h2>
+<p>Esta prévia aprimora o sistema de intenções do Android fornecendo vínculo de aplicativo mais poderoso.
+Este recurso permite que você associe um aplicativo com um domínio de web próprio. Com base nesta
+associação, a plataforma pode determinar o aplicativo padrão a ser usado para lidar com um link da web
+em particular e ignorar a solicitação aos usuários para selecionar um aplicativo. Para aprender como implementar este aplicativo, consulte
+<a href="{@docRoot}preview/features/app-linking.html">vínculo de aplicativo</a>.
+
+<h2 id="backup">Backup automático para aplicativos</h2>
+<p>O sistema agora realiza backup automático completo de dados e restauração para aplicativos. Este comportamento
+é ativado por padrão para aplicativos com M Preview; não é necessário mais código adicional. Se
+os usuários excluírem as contas da Google, os dados de backup também serão excluídos. Para aprender como este recurso
+funciona e como configurar o backup no sistema do arquivo, consulte
+<a href="{@docRoot}preview/backup/index.html">backup automático para aplicativos</a>.</p>
+
+<h2 id="authentication">Autenticação</h2>
+<p>Esta prévia oferece novas APIs para permitir que você autentique os usuários usando digitalizadores de impressão digital em dispositivos
+suportados e verifique o quão recentemente os usuários autenticaram pela última vez usando o
+mecanismo de desbloqueio por dispositivo (como senha de tela de bloqueio). Use essas APIs em conjunto com
+o <a href="{@docRoot}training/articles/keystore.html">sistema Android Keystore</a>.</p>
+
+<h3 id="fingerprint-authentication">Autenticação com impressão digital</h3>
+
+<p>Para autenticar os usuários por meio de digitalização de impressão digital, adquira uma instância da nova classe
+{@code android.hardware.fingerprint.FingerprintManager} e chame o método
+{@code FingerprintManager.authenticate()}. O aplicativo deve ser executado em um dispositivo
+compatível com sensor de impressão digital. Deve-se implementar a interface do usuário para o fluxo de autenticação
+de impressão digital no aplicativo e usar o ícone de impressão digital padrão do Android na IU.
+O ícone de impressão digital do Android ({@code c_fp_40px.png}) é incluído no
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">aplicativo de exemplo</a>. Caso esteja desenvolvendo vários aplicativos que usam
+autenticação de impressão digital, observe que cada aplicativo deve autenticar a impressão digital do usuário independentemente.
+</p>
+
+<p>Para usar este recurso no aplicativo, adicione primeiro a permissão {@code USE_FINGERPRINT} no
+manifesto.</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>Para ver a implementação do aplicativo da autenticação com impressão digital, consulte o
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
+ exemplo de caixa de diálogo de impressão digital</a>.</p>
+
+<p>Caso esteja testando este recurso, siga estas etapas:</p>
+<ol>
+<li>Instale o Android SDK Tools Revision 24.3, caso ainda não tenha instalado.</li>
+<li>Registre uma nova impressão digital no emulador acessando
+<strong>Configurações > Segurança > Impressão digital</strong> e, em seguida, siga as instruções de registro.</li>
+<li>Use um emulador para emular eventos de toque de dedo com o
+comando a seguir. Use o mesmo comando para emular os eventos de toque de impressão digital na tela de
+bloqueio ou no aplicativo.
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>No Windows, talvez seja necessário executar {@code telnet 127.0.0.1 <emulator-id>} seguido de
+{@code finger touch <finger_id>}.
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">Confirmação de credencial</h3>
+<p>O aplicativo pode autenticar os usuários com base no quão recentemente o dispositivo foi desbloqueado pela última vez. Este
+recurso libera o usuário de ter que lembrar de senhas específicas de aplicativo extras e evita
+a necessidade de implementar a própria interface do usuário de autenticação. O aplicativo deve usar este recurso
+em conjunto com uma implementação de chave secreta ou pública para a implementação de usuário.</p>
+
+<p>Para definir uma duração de tempo limite em que a mesma chave pode ser usada novamente
+após o usuário autenticar, chame o novo método
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+ ao definir um {@link javax.crypto.KeyGenerator} ou
+{@link java.security.KeyPairGenerator}. Este recurso funciona para operações criptográficas
+simétricas.</p>
+
+<p>Evite exibir o diálogo de nova autenticação excessivamente — os aplicativos devem tentar
+usar o objeto criptográfico primeiro e, se o tempo limite expirar, usar o método
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+ para autenticar novamente o usuário dentro do aplicativo.
+</p>
+
+<p>Para ver uma implementação de aplicativo deste recurso, consulte o
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">
+exemplo de confirmação de credencial</a>.</p>
+
+<h2 id="direct-share">Compartilhamento direto</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>Esta prévia fornece as APIs para tornar o compartilhamento intuitivo e rápido para os usuários. É possível
+definir os <em>alvos de compartilhamento direto</em> que iniciam uma atividade específica no aplicativo.
+Esses alvos de compartilhamento direto são expostos aos usuários por meio do menu <em>Compartilhar</em>. Este recurso permite que os usuários
+compartilhem conteúdos aos alvos, como contatos, dentro de outros aplicativos. Por exemplo: o alvo de compartilhamento direto
+pode iniciar uma atividade em outro aplicativo de rede social, o que permite que o usuário compartilhe o conteúdo diretamente
+para um amigo ou comunidade específica neste aplicativo.</p>
+
+<p>Para ativar os alvos de compartilhamento direto, deve-se definir uma classe que estende a classe
+{@code android.service.} <br>
+{@code chooser.ChooserTargetService}. Declare o
+{@code ChooserTargetService} no manifesto. Dentro desta declaração, especifique a permissão
+{@code BIND_CHOOSER_TARGET_SERVICE} e um filtro de intenções na ação
+{@code SERVICE_INTERFACE}.</p>
+<p>O seguinte exemplo mostra como se deve declarar o {@code ChooserTargetService} no
+manifesto.</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>Para cada atividade que quiser expor ao {@code ChooserTargetService}, adicione um elemento
+{@code <meta-data>} com o nome
+{@code "android.service.chooser.chooser_target_service"} no manifesto do aplicativo.
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">Interações por voz</h2>
+<p>
+Esta prévia fornece uma API de interação por voz que, junto com
+<a href="https://developers.google.com/voice-actions/" class="external-link">ações de voz</a>
+, permite a criação de experiências por voz nos aplicativos. Chame o método
+{@code android.app.Activity.isVoiceInteraction()} para determinar se a atividade
+foi iniciada em resposta à ação de voz. Caso tenha sido iniciada, o aplicativo pode usar a classe
+{@code android.app.VoiceInteractor} para solicitar uma confirmação de voz do usuário,
+selecionar a partir de uma lista de opções e muito mais. Para aprender mais sobre a implementação de ações de voz, consulte
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">o site de desenvolvedor de ações de voz</a>.
+</p>
+
+<h2 id="assist">Auxiliar API</h2>
+<p>
+Esta prévia oferece uma nova maneira de usuários se envolverem com os aplicativos com um assistente. Para usar este
+recurso, o usuário deve possibilitar que o assistente use o contexto atual. Quando ativado,
+o usuário pode invocar um assistente dentro de qualquer aplicativo mantendo o botão <strong>Iniciar</strong> pressionado.</p>
+<p>O aplicativo pode optar por não compartilhar o contexto atual com o assistente configurando o sinalizador
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE}. Além do conjunto
+padrão de informações que a plataforma passa ao assistente, o aplicativo pode compartilhar
+informações adicionais usando a nova classe {@code android.app.Activity.AssistContent}.</p>
+
+<p>Para fornecer ao assistente contexto adicional do aplicativo, siga estas etapas:</p>
+
+<ol>
+<li>Implemente a interface {@link android.app.Application.OnProvideAssistDataListener}.</li>
+<li>Registre esta escuta usando
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
+<li>Para fornecer informações contextuais específicas da atividade, substitua o retorno de chamada
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+ e, opcionalmente, o novo retorno de chamada {@code Activity.onProvideAssistContent()}.
+</ol>
+
+<h2 id="notifications">Notificações</h2>
+<p>Esta prévia adiciona as seguintes alterações de API às notificações:</p>
+<ul>
+ <li>Novo nível de filtro {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} que corresponde
+ao modo "não perturbe" de <em>despertadores apenas</em>.</li>
+ <li>Novo valor da categoria {@code Notification.CATEGORY_REMINDER} que é usado para distinguir
+lembretes de agendamentos do usuário de outros eventos (
+{@link android.app.Notification#CATEGORY_EVENT}) e despertadores (
+{@link android.app.Notification#CATEGORY_ALARM}).</li>
+ <li>Nova classe {@code android.graphics.drawable.Icon} que pode ser anexada às notificações
+por meio dos métodos {@code Notification.Builder.setSmallIcon(Icon)} e
+{@code Notification.Builder.setLargeIcon(Icon)}.</li>
+ <li>Novo método {@code NotificationManager.getActiveNotifications()} que permite que os aplicativos
+descubram quais das notificações ainda estão ativas. Para ver uma implementação de aplicativo que usa este recurso,
+consulte o <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">exemplo de notificações ativas</a>.</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Suporte para Bluetooth Stylus</h2>
+<p>Esta prévia fornece um suporte aprimorado para a entrada de usuário usando um Bluetooth Stylus. Os usuários podem
+parear e conectar um Bluetooth Stylus compatível com o telefone ou tablet. Quando conectado, as informações
+de posição da tela tátil são fundidas com as informações de botão e pressão do Stylus
+para fornecer um alcance maior de expressão em comparação à tela tátil sozinha. O aplicativo pode escutar o pressionar
+de botões do Stylus e realizar ações secundárias registrando os novos retornos de chamada
+{@code View.onStylusButtonPressListener} e {@code GestureDetector.OnStylusButtonPressListener}
+ na atividade.</p>
+
+<p>Use as constantes e os métodos {@link android.view.MotionEvent} para detectar as interações
+de botão do Stylus:</p>
+<ul>
+<li>Se o usuário toca no Stylus com um botão na tela do aplicativo, o método
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} retorna
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
+<li>Para aplicativos com M Preview, o método
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+ retorna {@code MotionEvent.STYLUS_BUTTON_PRIMARY} quando o usuário
+pressiona o botão principal do Stylus. Se o Stylus tiver um segundo botão, o mesmo método retorna
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY} quando o usuário o pressiona. Se o usuário pressiona
+os dois botões simultaneamente, o método retorna os valores com OR juntos (
+{@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).</li>
+<li>
+Para aplicativos com uma versão de plataforma inferior , o método
+{@link android.view.MotionEvent#getButtonState() getButtonState()} retorna
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (para o pressionar do botão principal do Stylus),
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (para o pressionar do botão secundário do Stylus) ou ambos.
+</li>
+</ul>
+
+<h2 id="ble-scanning">Digitalização de baixa energia por Bluetooth aprimorada</h2>
+<p>
+Se o aplicativo realizar digitalizações de baixa energia por Bluetooth, é possível usar o novo método
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} para especificar
+que você quer que os retornos de chamada sejam notificados apenas quando um pacote de propaganda correspondente ao conjunto
+{@link android.bluetooth.le.ScanFilter} for encontrado primeiro e quando
+ele não for visto por um período. Esta abordagem de digitalização é mais eficiente
+do que a fornecida na versão anterior da plataforma.
+</p>
+
+<h2 id="hotspot">Suporte a Hotspot 2.0 Release 1</h2>
+<p>
+Esta prévia adiciona suporte ao Hotspot 2.0 Release 1 nos dispositivos Nexus 6 e Nexus 9. Para fornecer
+as credenciais de Hotspot 2.0 no aplicativo, use os novos métodos da classe
+{@link android.net.wifi.WifiEnterpriseConfig}, como {@code setPlmn()} e
+{@code setRealm()}. No objeto {@link android.net.wifi.WifiConfiguration}, é possível definir os campos
+{@link android.net.wifi.WifiConfiguration#FQDN} e {@code providerFriendlyName}.
+A nova propriedade {@code ScanResult.PasspointNetwork} indica se uma rede detectada representa
+um ponto de acesso Hotspot 2.0.
+</p>
+
+<h2 id="4K-display">Modo de exibição 4K</h2>
+<p>A plataforma agora permite que aplicativos solicitem que a resolução seja aprimorada para renderização 4K
+em hardware compatível. Para consultar a resolução física atual, use as novas APIs
+{@code android.view.Display.Mode}. Se a IU for desenhada em uma resolução lógica
+menor e for redimensionada para uma resolução física maior, saiba que a resolução física que o método
+{@code Display.Mode.getPhysicalWidth()} retorna pode ser diferente da resolução
+física informada por {@link android.view.Display#getSize(android.graphics.Point) getSize()}.</p>
+
+<p>É possível solicitar que o sistema altere a resolução física no aplicativo à medida que ele é executado configurando
+a propriedade {@code WindowManager.LayoutParams.preferredDisplayModeId} da janela do aplicativo. Este
+recurso é útil se quiser alternar para a resolução de exibição 4K. Enquanto estiver no modo de exibição 4K,
+a IU continua a ser renderizada na resolução original (como 1080 p) e é escalonada para 4K, mas os objetos
+{@link android.view.SurfaceView} podem exibir o conteúdo na resolução nativa.</p>
+
+<h2 id="behavior-themeable-colorstatelists">ColorStateLists com tema</h2>
+<p>Os atributos de tema agora são suportados no
+{@link android.content.res.ColorStateList} para dispositivos que executam o M Preview. Os métodos
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} e
+{@link android.content.res.Resources#getColor(int) getColor()} ficaram obsoletos. Caso esteja chamando
+essas APIs, chame os novos métodos {@code Context.getColorStateList()} ou
+{@code Context.getColor()}. Esses métodos também estão disponíveis na biblioteca
+v4 appcompat via {@link android.support.v4.content.ContextCompat}.</p>
+
+<h2 id="audio">Recursos de áudio</h2>
+
+<p>Esta prévia adiciona aprimoramentos ao processamento de áudio no Android, incluindo: </p>
+<ul>
+ <li>Suporte para protocolo <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+, com as novas APIs {@code android.media.midi}. Use essas APIs para enviar e receber eventos
+de MIDI.</li>
+ <li>Use as novas classes {@code android.media.AudioRecord.Builder} e {@code android.media.AudioTrack.Builder}
+ para criar captura de áudio digital e objetos de reprodução, respectivamente,
+e configure a fonte de áudio e as propriedades do coletor para substituir os padrões do sistema.</li>
+ <li>Ganchos de API para associação de dispositivos de entrada e áudio. Isto é particularmente útil se o aplicativo
+permite que os usuários iniciem uma pesquisa de voz a partir de um controle de jogo ou controle remoto para Android
+TV. O sistema invoca o novo retorno de chamada {@code android.app.Activity.onSearchRequested()} quando
+o usuário inicia uma pesquisa. Para determinar se o dispositivo de entrada do usuário tem um microfone integrado, recupere
+o objeto {@link android.view.InputDevice} deste retorno de chamada e, em seguida, chame o novo método
+{@code InputDevice.hasMic()}.</li>
+ <li>Novas classes {@code android.media.AudioDevicesManager} que permitem que você
+recupere uma lista completa de todas as fontes e dispositivos de áudio do coletor anexados. Também é possível especificar um objeto
+{@code android.media.OnAudioDeviceConnectionListener} caso queira que o aplicativo seja notificado
+quando um dispositivo de áudio for conectado ou desconectado.</li>
+</ul>
+
+<h2 id="video">Recursos de vídeo</h2>
+<p>Esta prévia adiciona novas capacidades às APIs de processamento de vídeo, incluindo:</p>
+<ul>
+<li>A nova classe {@code android.media.MediaSync} que ajuda os aplicativos a renderizar transmissões
+de vídeo e áudio sincronizadamente. Os buffers de áudio são enviados sem bloqueio e retornados
+por um retorno de chamada. Eles também suportam taxa de reprodução dinâmica.
+</li>
+<li>O novo evento {@code MediaDrm.EVENT_SESSION_RECLAIMED}, que indica que uma sessão aberta pelo aplicativo
+foi recuperada pelo gerenciador de recursos. Se o aplicativo usa sessões de DRM, deve-se
+lidar com este evento e garantir que uma sessão recuperada não seja usada.
+</li>
+<li>O novo código de erro {@code MediaCodec.CodecException.ERROR_RECLAIMED}, que indica que o gerenciador
+de recurso recuperou o recurso de mídia usado pelo codec. Com esta exceção, o codec
+deve ser liberado, como se fosse movido para o estado terminal.
+</li>
+<li>A nova interface {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} para obter
+uma dica do número máximo suportado de instâncias de codec concorrentes.
+</li>
+<li>O novo método {@code MediaPlayer.setPlaybackParams()} para definir a taxa de reprodução de mídia
+para reprodução de movimento lento ou rápido. Ele também estica ou acelera a reprodução de áudio automaticamente
+em conjunto com o vídeo.</li>
+</ul>
+
+<h2 id="camera">Recursos de câmera</h2>
+<p>Esta prévia inclui as seguintes novas APIs para acessar a lanterna da câmera
+e para o reprocessamento da câmera de imagens:</p>
+
+<h3 id="flashlight">API da lanterna</h3>
+<p>Se um dispositivo de câmera tem uma unidade de flash, é possível chamar o método {@code CameraManager.setTorchMode()}
+para ligar ou desligar o modo de tocha da unidade de flash sem abrir o dispositivo da câmera. O aplicativo
+não tem propriedade exclusiva da unidade de flash ou do dispositivo de câmera. O modo de tocha é desativado
+e torna-se indisponível sempre que o dispositivo de câmera estiver indisponível ou quando outros
+recursos de câmera que mantêm a tocha ativada ficam indisponíveis. Outros aplicativos também podem chamar {@code setTorchMode()}
+para desativar o modo de tocha. Quando o aplicativo que ativou o modo
+de tocha for fechado, o modo é desativado.</p>
+
+<p>É possível registrar um retorno de chamada para ser notificado sobre o estado da tocha chamando o método
+{@code CameraManager.registerTorchCallback()}. Na primeira vez que o retorno de chamada é registrado,
+ele é imediatamente chamado com o estado do modo de tocha de todos os dispositivos de câmera conhecidos com
+uma unidade de flash. Se o modo de tocha é ativado ou desativado, o método
+{@code CameraManager.TorchCallback.onTorchModeChanged()} é invocado.</p>
+
+<h3 id="reprocessing">API de reprocessamento</h3>
+<p>A API {@link android.hardware.camera2 Camera2} é estendida para suportar YUV e reprocessamento
+de imagem de formato opaco privado. O aplicativo determina se as capacidades de reprocessamento estão disponíveis
+via {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}. Se um dispositivo suporta o reprocessamento,
+é possível criar uma sessão de captura de câmera de reprocessamento chamando
+{@code CameraDevice.createReprocessableCaptureSession()} e criando solicitações para o reprocessamento
+do buffer de entrada.</p>
+
+<p>Use a classe {@code ImageWriter} para conectar o fluxo de buffer de entrada à entrada de reprocessamento
+da câmera. Para obter um buffer vazio, siga este modelo de programação:</p>
+
+<ol>
+<li>Chame o método {@code ImageWriter.dequeueInputImage()}.</li>
+<li>Preencha os dados no buffer de entrada.</li>
+<li>Envie o buffer à câmera chamando o método {@code ImageWriter.queueInputImage()}.</li>
+</ol>
+
+<p>Caso esteja usando um objeto {@code ImageWriter} junto com uma imagem
+{@code android.graphics.ImageFormat.PRIVATE}, o aplicativo não poderá acessar os dados
+da imagem diretamente. Em vez disso, passe a imagem {@code ImageFormat.PRIVATE} diretamente ao
+{@code ImageWriter} chamando o método {@code ImageWriter.queueInputImage()} sem nenhuma
+cópia de buffer.</p>
+
+<p>A classe {@code ImageReader} agora suporta as transmissões de imagem
+de formato {@code android.graphics.ImageFormat.PRIVATE}. Este suporte permite que o aplicativo mantenha uma fila de imagem circular de imagens de saída
+{@code ImageReader}, selecione uma ou mais imagens e envie-as para
+{@code ImageWriter} para o reprocessamento de câmera.</p>
+
+<h2 id="afw">Recursos do Android for Work</h2>
+<p>Esta prévia inclui as seguintes novas APIs para Android for Work:</p>
+<ul>
+ <li><strong>Controles aprimorados para dispositivos de uso único e pertencentes a empresas:</strong> O dono do dispositivo
+pode controlar as seguintes configurações para aprimorar
+os dispositivos de uso único pertencentes a empresas (COSU):
+ <ul>
+ <li>Desativar ou reativar a proteção de bloqueio com o método
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Desativar ou reativar a barra de status (incluindo configurações rápidas,
+notificações e o gesto de arrastar para cima que inicia o Google Now) com o método
+{@code DevicePolicyManager.setStatusBarEnabledState()}.</li>
+ <li>Desativar ou reativar inicialização segura com a constante {@link android.os.UserManager}
+{@code DISALLOW_SAFE_BOOT}.</li>
+ <li>Evitar que a tela desligue quando conectada com a constante
+{@link android.provider.Settings.Global} {@code STAY_ON_WHILE_PLUGGED_IN}.</li>
+ </ul>
+ </li>
+ <li><strong>Instalação e desinstalação silenciosa de aplicativos pelo dono do dispositivo:</strong> O dono do dispositivo pode agora
+instalar e desinstalar aplicativos silenciosamente usando as APIs {@link android.content.pm.PackageInstaller},
+independente do Google Play for Work. É possível tomar providências para os dispositivos
+por meio de um dono do dispositivo que recupera e instala aplicativos se a interação de usuário. Este recurso é útil para ativar a provisão de um toque
+de telefones públicos ou de outros dispositivos sem a ativação da conta Google.</li>
+<li><strong>Acesso silencioso de certificado empresarial: </strong> Quando um aplicativo chama
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()}
+, antes do usuário receber a solicitação para selecionar um certificado, o perfil ou dono do dispositivo
+pode chamar o método {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} para fornecer
+o alias silenciosamente ao aplicativo da solicitação. Este recurso permite que você forneça acesso de aplicativos gerenciados para certificados
+sem a interação de usuário.</li>
+<li><strong>Aceitação automática de atualizações do sistema.</strong> Ao configurar a política de atualização do sistema com
+{@code DevicePolicyManager.setSystemUpdatePolicy()}, o dono do dispositivo pode aceitar automaticamente a atualização
+do sistema, no caso de um dispositivo público, ou adiar a atualização e evitar
+que ela seja feita pelo usuário por até 30 dias. Além disso, um administrador pode definir uma janela de tempo diária
+em que uma atualização deve ser realizada. Por exemplo: durante os momentos em que um dispositivo público não está em uso. Quando
+uma atualização do sistema está disponível, o sistema verifica se o aplicativo de controlador de política de trabalho definiu uma política de atualização
+do sistema e, portanto, comporta-se de acordo com a definição.
+</li>
+<li>
+<strong>Instalação de certificado delegado:</strong> Um perfil ou dono do dispositivo pode agora fornecer ao aplicativo
+de terceiros a habilidade de chamar essas APIs de gerenciamento
+de certificado de {@link android.app.admin.DevicePolicyManager}:
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>Proteção de redefinição de fábrica da empresa:</strong> Ao preparar um dono do dispositivo, agora é possível
+configurar parâmetros para desbloquear a proteção de redefinição de fábrica (FRP) configurando o pacote
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}. Um aplicativo de programador
+NFC pode fornecer estes parâmetros depois que um dispositivo for redefinido para desbloquear o FRP e preparar o dispositivo,
+sem a necessidade da conta Google anteriormente configurada. Caso não modifique esses parâmetros,
+o FRP permanece no local e evita que o dispositivo seja ativado sem as credenciais
+Google anteriormente ativadas.
+<p>Além disso, ao configurar as restrições do aplicativo nos serviços Google, o dono do dispositivo pode especificar contas
+Google alternativas para desbloquear o FRP para substituir as contas ativadas no dispositivo.</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>Rastreamento de uso de dados.</strong> Um perfil ou dono do dispositivo pode agora
+consultar as estatísticas de uso de dados visíveis em <strong>Configurações > Uso de</strong> dados usando os novos métodos
+{@code android.app.usage.NetworkStatsManager}. Os donos de perfis recebem automaticamente
+a permissão para consultar os dados no perfil que gerenciam, enquanto que os donos do dispositivo têm acesso aos dados
+de uso do usuário principal gerenciado.</li>
+<li><strong>Gerenciamento de permissão de tempo de execução:</strong>
+<p>Um perfil ou dono do dispositivo pode definir uma política
+de permissão para todas as solicitações do tempo de execução de todos os aplicativos que usam
+{@code DevicePolicyManager.setPermissionPolicy()}, seja para solicitar ao usuário para conceder
+a permissão como normal ou automaticamente conceder ou negar a permissão silenciosamente. Se a política posterior
+for definida, o usuário não poderá modificar a seleção feita pelo perfil ou dono do dispositivo dentro da tela de permissões
+do aplicativo em <strong>configurações</strong>.</p></li>
+<li><strong>VPN em configurações:</strong> Os aplicativos de VPN agora estão visíveis em
+<strong>Configurações > Mais > VPN</strong>.
+Além disso, as notificações que acompanham o uso de VPN são específicas sobre como essa VPN
+é configurada. Para o dono de um perfil, as notificações são específicas para determinar
+se a VPN é configurada para um perfil gerenciado, um perfil pessoal ou ambos. Para o dono do dispositivo, as notificações
+são específicas para determinar se a VPN é configurada para todo o dispositivo.</li>
+<li><strong>Notificação de estado de trabalho:</strong> Um ícone de pasta da barra de status agora aparece
+sempre que um aplicativo do perfil gerenciado tiver uma atividade no primeiro plano. Além disso, se o usuário é desbloqueado
+diretamente para a atividade de um aplicativo no perfil gerenciado, um aviso é exibido notificando
+ao usuário que ele está dentro do perfil de trabalho.
+</li>
+</ul>
+
+<p class="note">
+ Para obter uma vista detalhada de todas as alterações de API no M Developer Preview, consulte o <a href="{@docRoot}preview/download.html">relatório de diferenças de API</a>.
+</p>
diff --git a/docs/html-intl/intl/pt-br/preview/behavior-changes.jd b/docs/html-intl/intl/pt-br/preview/behavior-changes.jd
new file mode 100644
index 0000000..cd99bbd
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=Mudanças de comportamento
+page.keywords=preview,sdk,compatibility
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Neste documento</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">Permissões do tempo de execução</a></li>
+ <li><a href="#behavior-power">Otimizações de economia de energia</a>
+ <ol>
+ <li><a href="#behavior-doze">Soneca</a></li>
+ <li><a href="#behavior-app-standby">Aplicativo em espera</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">Dispositivos de armazenamento adotáveis</a></li>
+ <li><a href="#behavior-apache-http-client">Remoção do cliente Apache HTTP</a></li>
+ <li><a href="#behavior-audiomanager-Changes">Mudanças no AudioManager</a></li>
+ <li><a href="#behavior-test-selection">Seleção de texto</a></li>
+ <li><a href="#behavior-keystore">Mudanças no Android Keystore</a></li>
+ <li><a href="#behavior-network">Mudanças de rede e Wi-Fi</a></li>
+ <li><a href="#behavior-camera">Mudanças no serviço de câmera</a></li>
+ <li><a href="#behavior-art-runtime">Tempo de execução de ART</a></li>
+ <li><a href="#behavior-apk-validation">Validação de APK</a></li>
+ <li><a href="#behavior-afw">Mudanças do Android for Work</a></li>
+</ol>
+
+<h2>Diferenças de API</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API de nível 22 para M Preview »</a> </li>
+</ol>
+
+
+<h2>Veja também</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Visão geral da API do M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Junto com novas capacidades e recursos, o M Developer Preview inclui uma variedade
+de mudanças do sistema e alterações no comportamento da API. Este documento destaca algumas
+das alterações principais que você deve entender e levar em consideração nos aplicativos.</p>
+
+<p>Caso tenha publicado anteriormente um aplicativo para Android, saiba que ele pode ser afetado
+ pelas alterações na plataforma.</p>
+
+<h2 id="behavior-runtime-permissions">Permissões do tempo de execução</h1>
+<p>Esta prévia introduz um novo modelo de permissões em que os usuários podem gerenciar diretamente
+ as permissões do aplicativo no tempo de execução. Este modelo fornece aos usuários uma visibilidade aprimorada e controle sobre permissões,
+ ao mesmo tempo em que agiliza os processos de atualização automática e instalação para os desenvolvedores de aplicativos.
+Os usuários podem conceder ou revogar as permissões individualmente para os aplicativos instalados. </p>
+
+<p>Nos aplicativos direcionados para o M Preview, certifique-se de verificar e solicitar as permissões
+ no tempo de execução. Para determinar se o aplicativo recebeu uma permissão, chame
+ o novo método {@code Context.checkSelfPermission()}. Para solicitar uma permissão, chame o novo método
+ {@code Activity.requestPermission()}. Mesmo se o aplicativo não é direcionado para o M,
+ deve-se testá-lo sob o novo modelo de permissões.</p>
+
+<p>Para obter mais detalhes sobre o suporte do novo modelo de permissões no aplicativo, consulte a página de prévia de desenvolvedor
+<a href="{@docRoot}preview/features/runtime-permissions.html">
+Permissões</a>. Para obter dicas sobre como avaliar o impacto no aplicativo,
+ consulte o <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">guia de teste</a>.</p>
+
+<h2 id="behavior-power">Otimizações de economia de energia</h2>
+<p>Esta prévia introduz novas otimizações de economia de energia para dispositivos e aplicativos ociosos.</p>
+
+<h3 id="behavior-doze">Soneca</h3>
+<p>Se o dispositivo estiver desconectado e parado com a tela desligada por um período,
+ o modo <em>Soneca</em> será ativado, onde ele tentará manter o sistema em um estado ocioso. Neste modo,
+ os dispositivos retomam as operações normais periodicamente por breves períodos para que a sincronização de aplicativos
+ possa ocorrer e para que o sistema possa realizar quaisquer operações pendentes.</p>
+
+<p>As seguintes restrições se aplicam aos aplicativos durante a Soneca:</p>
+<ul>
+<li>O acesso à rede é desativado, a não ser que o aplicativo receba um convite de alta prioridade
+ do Google Cloud Messaging.</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">Bloqueios de soneca</a> são ignorados.</li>
+<li>Os despertadores agendados com a classe {@link android.app.AlarmManager} são ignorados,
+ exceto os alarmes definidos com o método {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+ e {@code AlarmManager.setAndAllowWhileIdle()}.</li>
+<li>As verificações de Wi-Fi não são realizadas.</li>
+<li>Sincronizações e trabalhos para os adaptadores de sincronização e {@link android.app.job.JobScheduler}
+ não têm permissão para serem executados.</li>
+</ul>
+</p>
+<p>Quando o dispositivo sair do modo soneca, quaisquer sincronizações e trabalhos pendentes são executados.</p>
+<p>É possível testar este recurso conectando o dispositivo executando o M Preview
+ à máquina de desenvolvimento e chamando os seguintes comandos:
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>Observação</strong>: o próximo lançamento do
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> permite que você designe
+ mensagens de alta prioridade. Se o aplicativo recebe mensagens de alta prioridade do GCM,
+ um acesso breve à rede é concedido mesmo quando o dispositivo está no modo soneca.
+</p>
+
+<p>Consulte o
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">guia de teste</a> para obter dicas sobre
+como testar a soneca nos aplicativos. </p>
+
+<h3 id="behavior-app-standby">Aplicativo em espera</h3>
+<p>Com esta prévia, o sistema pode determinar quais aplicativos estão em espera quando
+não estão em uso ativo. O aplicativo é considerado em espera após um período, a não ser que o sistema detecte
+algum destes sinais:</p>
+
+<ul>
+<li>O aplicativo foi explicitamente iniciado pelo usuário.</li>
+<li>O aplicativo tem um processo atualmente em primeiro plano (seja uma atividade ou serviço de primeiro plano
+ ou esteja em uso por outra atividade ou serviço de primeiro plano).</li>
+<li>O aplicativo gera uma notificação que o usuário vê na tela de bloqueio
+ ou na bandeja de notificações.</li>
+<li>O usuário explicitamente pede para que o aplicativo seja liberado das otimizações,
+ ajustado em <strong>Settings (Configurações)</strong>.</li>
+</ul>
+
+<p>Se o dispositivo estiver desconectado, o aplicativo considerado ocioso terá o acesso
+à rede desativado e as sincronizações e os trabalhos suspensos. Quando o dispositivo está conectado em uma fonte de alimentação,
+ esses aplicativos têm acesso à rede permitido e podem executar quaisquer sincronizações e trabalhos pendentes. Se o dispositivo permanece ocioso por longos períodos,
+ os aplicativos ociosos têm acesso à rede permitido aproximadamente uma vez por dia.</p>
+
+<p>É possível testar este recurso conectando o dispositivo executando o M Preview
+ à máquina de desenvolvimento e chamando os seguintes comandos:
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>Observação</strong>: o próximo lançamento do
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+Google Cloud Messaging</a> (GCM) permite que você
+designe mensagens de alta prioridade. Se o aplicativo recebe mensagens de alta prioridade do GCM,
+um acesso breve à rede é concedido mesmo quando o aplicativo está ocioso.
+</p>
+
+<p>Consulte o
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">guia de teste</a> para obter dicas sobre como
+testar a espera dos aplicativos. </p>
+
+<h2 id="behavior-adoptable-storage">Dispositivos de armazenamento adotáveis</h2>
+<p>
+Com esta prévia, os usuários podem <em>adotar</em> dispositivos de armazenamento externo como cartões SD. Adotar um dispositivo
+de armazenamento externo criptografa e formata o dispositivo para agir como um armazenamento interno. Este recurso
+permite que os usuários movam aplicativos e dados privados desses aplicativos entre dispositivos de armazenamento. Ao mover aplicativos,
+o sistema respeita a preferência
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+no manifesto.</p>
+
+<p>Se o aplicativo acessar as seguintes APIs ou campos, saiba que os caminhos de arquivos retornados
+serão alterados dinamicamente quando o aplicativo for movido entre os dispositivos de armazenamento externo e interno.
+Ao compilar caminhos de arquivos, é recomendado que essas APIs sempre sejam chamadas dinamicamente.
+Não use caminhos de arquivo criptografados nem persista em caminhos de arquivo completamente qualificados que foram compilados anteriormente.</p>
+
+<ul>
+<li>Métodos {@link android.content.Context}:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>Campos {@link android.content.pm.ApplicationInfo}:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>Para depurar este recurso na prévia de desenvolvedor, é possível ativar a adoção
+de uma unidade USB que está conectada a um dispositivo Android por meio de um cabo USB On-The-Go (OTG) executando este comando:</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Remoção do cliente Apache HTTP</h2>
+<p>Esta prévia remove o suporte para o cliente Apache HTTP. Se o aplicativo estiver usando este cliente e for direcionado
+para Android 2.3 (nível da API 9) ou mais recente, use
+a classe {@link java.net.HttpURLConnection}. Esta API é mais eficiente, pois reduz o uso de rede por meio de compressão transparente e armazenamento
+em cachê de respostas, além de minimizar o consumo de energia. Para continuar usando as APIs do Apache HTTP,
+deve-se primeiro declarar a dependência de tempo de compilação no arquivo {@code build.gradle}:
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>O Android está mudando da biblioteca OpenSSL para
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Caso esteja usando o Android NDK no aplicativo, não vincule contra bibliotecas criptográficas
+que não fazem parte da API de NDK, como {@code libcrypto.so} e {@code libssl.so}. Estas bibliotecas não são APIs públicas
+e podem mudar ou apresentar erros sem notificar entre liberações e dispositivos.
+Além disso, você pode se expor a vulnerabilidades de segurança. Em vez disso,
+modifique o código nativo para chamar as APIs de criptografia Java via JNI ou para vincular estaticamente
+com relação a uma biblioteca criptográfica de sua escolha.</p>
+
+<h2 id="behavior-audiomanager-Changes">Mudanças no AudioManager</h2>
+<p>Ajustar o volume diretamente ou desativar o áudio de transmissões específicas por meio da classe {@link android.media.AudioManager}
+não são mais recursos suportados. O método {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} é obsoleto e deve-se chamar o método
+{@code AudioManager.requestAudioFocus()}. De forma semelhante, o método
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} é
+obsoleto; em vez disso, chame o método {@code AudioManager.adjustStreamVolume()}
+e passe o valor da direção de {@code ADJUST_MUTE} ou {@code ADJUST_UNMUTE}.</p>
+
+<h2 id="behavior-test-selection">Seleção de texto</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>Quando os usuários selecionam o texto no aplicativo, agora é possível exibir ações de seleção de texto como
+<em>Recortar</em>, <em>Copiar</em> e <em>Colar</em> na
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">barra de ferramentas flutuante</a>. A implementação da interação do usuário é semelhante ao processo
+da barra de ação contextual, como descrito em
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">
+Ativação do modo de ação contextual para vistas individuais</a>.</p>
+
+<p>Para implementar uma barra de ferramentas flutuante para seleção de texto, faça as seguintes alterações nos aplicativos
+existentes:</p>
+<ol>
+<li>No objeto {@link android.view.View} ou {@link android.app.Activity}, altere as chamadas
+{@link android.view.ActionMode} de
+{@code startActionMode(Callback)} para {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
+<li>Pegue a implementação existente de {@code ActionMode.Callback} e torne-a uma extensão de
+{@code ActionMode.Callback2}.</li>
+<li>Substitua o método {@code Callback2.onGetContentRect()} para fornecer as coordenadas do conteúdo
+do objeto {@link android.graphics.Rect} (como um retângulo de seleção de texto) na vista.</li>
+<li>Se o posicionamento do retângulo deixar de ser válido e for o único elemento a ser invalidado,
+chame o método {@code ActionMode.invalidateContentRect()}.</li>
+</ol>
+
+<p>Caso esteja usando a <a href="{@docRoot}tools/support-library/index.html">
+biblioteca de suporte Android</a> revisão 22.2, saiba que as barras de ferramentas flutuantes não
+têm compatibilidade com versões anteriores e que o appcompat tem controle sobre os objetos {@link android.view.ActionMode} por
+padrão. Isto evita que barras de ferramentas flutuantes sejam exibidas. Para ativar o suporte de
+{@link android.view.ActionMode} em um
+{@link android.support.v7.app.AppCompatActivity}, chame
+{@code android.support.v7.app.AppCompatActivity.getDelegate()} e, em seguida, chame
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} no objeto
+{@link android.support.v7.app.AppCompatDelegate} retornado e defina
+o parâmetro de entrada para {@code false}. Esta chamada retorna o controle dos objetos {@link android.view.ActionMode}
+à estrutura. Em dispositivos que são executados no M Preview, isto permite que a estrutura suporte os modos de
+{@link android.support.v7.app.ActionBar} ou de barra de ferramenta flutuante, enquanto que, para dispositivos anteriores ao M Preview,
+somente os modos {@link android.support.v7.app.ActionBar} são suportados.</p>
+
+<h2 id="behavior-keystore">Mudanças no Android Keystore</h2>
+<p>Com esta prévia,
+o <a href="{@docRoot}training/articles/keystore.html">provedor Android Keystore</a> não suporta mais
+DSA. ECDSA ainda é suportado.</p>
+
+<p>As chaves que não exigem criptografia em rest não precisam ser excluídas quando a tela de bloqueio segura
+é desativada ou redefinida (por exemplo, pelo usuário ou por um administrador do dispositivo). As chaves que exigem
+criptografia serão excluídas durante esses eventos.</p>
+
+<h2 id="behavior-network">Mudanças de rede e Wi-Fi</h2>
+
+<p>Esta prévia introduz as seguintes alterações de comportamento nas APIs de rede e Wi-Fi.</p>
+<ul>
+<li>Os aplicativos podem alterar o estado dos objetos {@link android.net.wifi.WifiConfiguration}
+somente se você os tiver criado. Você não tem permissão para modificar nem excluir objetos
+{@link android.net.wifi.WifiConfiguration} criados pelo usuário ou outros aplicativos.
+</li>
+<li>
+Anteriormente, se um aplicativo forçasse o dispositivo a se conectar a uma rede Wi-Fi específica usando
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} com a configuração
+{@code disableAllOthers=true}, o dispositivo desconectava de outras redes,
+como dados de celular. Nesta prévia, o dispositivo não rompe a conexão com outras redes. Se
+o {@code targetSdkVersion} do aplicativo for {@code “20”} ou menor, ele é fixado
+à rede Wi-Fi selecionada. Se o {@code targetSdkVersion} do aplicativo for {@code “21”} ou maior, use
+as APIS de multi-rede (como
+{@link android.net.Network#openConnection(java.net.URL) openConnection()},
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} e o novo método
+{@code ConnectivityManager.bindProcessToNetwork()}) para garantir que o tráfego de rede
+seja enviado na rede selecionada.</li>
+</ul>
+
+<h2 id="behavior-camera">Mudanças no serviço de câmera</h2>
+<p>Nesta prévia, o modelo para acessar recursos compartilhados no serviço de câmera foi alterado
+do antigo modelo de acesso “primeiro a chegar, primeiro a ser atendido” para um modelo de acesso onde
+os processos de alta prioridade são favorecidos. As mudanças no comportamento do serviço incluem:</p>
+<ul>
+<li>Acesso aos recursos do subsistema da câmera, incluindo abertura e configuração de um dispositivo de câmera,
+concedido com base na prioridade do processo do aplicativo do cliente. Processos de aplicativos com atividades
+visíveis ao usuário ou de primeiro plano são geralmente de alta prioridade, tornando a aquisição
+e o uso de recursos da câmera mais dependentes.</li>
+<li>Clientes de câmera ativa para aplicativos de menor prioridade podem ser "despejados" quando
+um aplicativo de alta prioridade tenta usar a câmera. Na API {@link android.hardware.Camera} obsoleta,
+isto resulta em
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} sendo
+chamado para o cliente despejado. Na API {@link android.hardware.camera2 Camera2}, isto resulta em
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
+sendo chamado para o cliente despejado.</li>
+<li>Em dispositivos com hardware de câmera adequado, processos de aplicativo separados podem
+abrir e usar independentemente os dispositivos de câmera simultaneamente. No entanto, casos de uso de vários processos
+em que o acesso simultâneo causa uma degradação significante de desempenho ou capacidades
+de qualquer um dos dispositivos de câmera abertos agora são detectados e proibidos pelo serviço da câmera. Esta alteração
+pode resultar em "despejos" para clientes de menor prioridade quando nenhum aplicativo está
+tentando acessar o mesmo dispositivo de câmera diretamente.
+</li>
+<li>
+Alterar o usuário atual faz com que os clientes da câmera ativa em aplicativos pertencentes à conta do usuário anterior
+sejam despejados. O acesso à câmera é limitado a perfis de usuário pertencentes ao usuário do dispositivo atual.
+Na prática, isso significa que uma conta de "convidado", por exemplo, não poderá deixar
+processos em execução que usam o subsistema da câmera quando o usuário alternar para uma conta diferente.
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">Tempo de execução de ART</h2>
+<p>O tempo de execução de ART agora implementa adequadamente as regras de acesso
+para o método {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()}. Esta
+alteração corrige um problema onde o Dalvik estava verificando as regras de acesso incorretamente em versões anteriores.
+Se o aplicativo usa o método
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} e você quer
+substituir as verificações de acesso, chame o método
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} com o parâmetro
+de entrada definido como {@code true}. Se o aplicativo usar a
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">biblioteca v7 appcompat</a> ou a
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">biblioteca v7 recyclerview</a>,
+deve-se atualizá-lo para usar as versões mais recentes dessas bibliotecas. Caso contrário, certifique-se
+de que as classes personalizadas mencionadas a partir do XML sejam atualizadas para que os construtores de classe estejam acessíveis.</p>
+
+<p>Esta prévia atualiza o comportamento do vinculador dinâmico. O vinculador dinâmico agora entende
+a diferença entre um {@code soname} da biblioteca e o seu caminho
+(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+erro público 6670</a>), e a pesquisa por {@code soname}
+agora está implementada. Os aplicativos que anteriormente trabalhavam e têm entradas {@code DT_NEEDED} inválidas
+(geralmente, caminhos absolutos no sistema de arquivo na máquina de programação) podem falhar ao serem carregados.</p>
+
+<p>O sinalizador {@code dlopen(3) RTLD_LOCAL} agora está corretamente implementado. Observe que
+{@code RTLD_LOCAL} é o padrão. Portanto, chamadas para {@code dlopen(3)} que não usam explicitamente
+{@code RTLD_LOCAL} serão afetadas (a não ser que o aplicativo tenha usado explicitamente {@code RTLD_GLOBAL}). Com
+{@code RTLD_LOCAL}, os símbolos não estarão disponíveis para as bibliotecas carregadas por chamadas posteriores a
+{@code dlopen(3)} (o oposto ocorre quando mencionado por entradas {@code DT_NEEDED}).</p>
+</p>
+
+<h2 id="behavior-apk-validation">Validação de APK</h2>
+<p>A plataforma agora realiza validações mais estritas de APKs. Um APK é considerado corrompido se um arquivo
+for declarado no manifesto, mas não estiver presente no próprio APK. Um APK deve ser atribuído novamente se qualquer
+conteúdo for removido.</p>
+
+<h2 id="behavior-afw">Mudanças do Android for Work</h2>
+<p>Esta prévia inclui as seguintes mudanças de comportamento para Android for Work:</p>
+<ul>
+<li><strong>Contatos de trabalho em contextos pessoais.</strong> O registro de chamadas do telefone do Google
+agora exibe os contatos de trabalho quando o usuário visualiza chamadas anteriores.
+A configuração {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} para {@code true} oculta
+os contatos do perfil de trabalho no registro de chamadas do telefone. Os contatos de trabalho podem ser exibidos junto com os contatos pessoais
+aos dispositivos por meio de Bluetooth somente
+se {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} estiver definido como {@code false}. Por
+padrão, ele está definido como {@code true}.
+</li>
+<li><strong>Remoção de configuração Wi-Fi:</strong> as configurações de Wi-Fi adicionadas por um dono de perfil
+(por exemplo, por meio de chamadas para o método
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}) agora são removidas se esse perfil de trabalho é excluído.</li>
+<li><strong>Bloqueio de configuração Wi-Fi:</strong> qualquer configuração Wi-Fi criada por um dono do dispositivo
+ativo não pode mais ser modificada nem excluída pelo usuário. O usuário ainda pode criar
+e modificar as próprias configurações de Wi-Fi, contanto que a constante {@link android.os.UserManager}
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} não tenha sido definida por ele.</li>
+<li><strong>Faça o download do Work Policy Controller por meio de uma adição de conta Google:</strong> quando uma conta Google
+que requer um gerenciamento por meio do aplicativo Work Policy Controller (WPC) é adicionada ao dispositivo
+fora de um contexto gerenciado, o fluxo de conta adicionada agora solicita ao usuário para instalar
+o WPC adequado. Este comportamento também se aplica a contas adicionadas por meio de
+<strong>Settings (Configurações) > Accounts (Contas)</strong> no assistente de configuração inicial do dispositivo.</li>
+<li><strong>Alterações aos comportamentos específicos da API DevicePolicyManager:</strong>
+chamar o método {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+afeta a câmera somente para o usuário que realizou a chamada. Chamá-lo a partir do perfil gerenciado
+não afeta os aplicativos de câmera em execução no usuário principal. Além disso,
+o método {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+agora está disponível para donos de perfil, além dos donos do dispositivo. Um dono de perfil pode definir
+estas restrições de proteção de bloqueio:
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} e
+ {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, que afetam
+ as configurações de proteção de bloqueio para o usuário pai do perfil.</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, que
+ afeta somente as notificações geradas por aplicativos no perfil gerenciado.</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd b/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..762e1ae
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=Permissões
+page.tags=previewresources, androidm
+page.keywords=permissions, runtime, preview
+page.image={@docRoot}preview/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Visualização rápida</h2>
+ <ul>
+ <li>Se o aplicativo direciona o M Preview SDK, ele indica aos usuários para conceder
+ permissões no tempo de execução, em vez de tempo de instalação.</li>
+ <li>Os usuários podem revogar as permissões a qualquer momento na tela de configurações
+do aplicativo.</li>
+ <li>O aplicativo precisa verificar se tem as permissões necessárias
+sempre que for executado.</li>
+ </ul>
+
+ <h2>Neste documento</h2>
+ <ol>
+ <li><a href="#overview">Visão geral</a></li>
+ <li><a href="#coding">Codificação para permissões de tempo de execução</a></li>
+ <li><a href="#testing">Teste de permissões de tempo de execução</a></li>
+ <li><a href="#best-practices">Práticas recomendadas</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ O M Developer Preview introduz um novo modelo de permissões de aplicativo
+que agiliza o processo de instalação e atualização de aplicativos para os usuários. Se um aplicativo
+ que está sendo executado no M Preview suporta o novo modelo de permissões, o usuário não precisa conceder
+ permissões ao instalar ou atualizar o aplicativo. Em vez disso, o aplicativo
+ solicita as permissões à medida que precisar e o sistema exibe um diálogo
+ ao usuário pedindo a permissão.
+</p>
+
+<p>
+ Se um aplicativo suportar o novo modelo de permissões, ele
+ ainda poderá ser instalado e executado em versões mais antigas do Android, usando o antigo modelo
+ de permissões nesses dispositivos.
+</p>
+
+<h2 id="overview">
+ Visão geral
+</h2>
+
+<p>
+ Com o M Developer Preview, a plataforma introduz um novo modelo
+ de permissões. Eis um resumo dos componentes essenciais deste novo modelo:
+</p>
+
+<ul>
+ <li>
+ <strong>Declaração de permissões:</strong> O aplicativo declara todas
+ as permissões necessárias no manifesto, como nas plataformas anteriores do Android.
+ </li>
+
+ <li>
+ <strong>Grupos de permissão:</strong> As permissões são divididas em
+<em>grupos de permissão</em>, baseados na funcionalidade. Por exemplo: o grupo de permissão
+ <code>CONTACTS</code> contém permissões para ler e escrever
+ informações de perfil e contatos do usuário.
+ </li>
+
+ <li>
+ <p><strong>Permissões limitadas concedidas no tempo de instalação:</strong> Quando o usuário
+ instala ou atualiza o aplicativo, o sistema concede todas
+ as permissões que o aplicativo solicita que estão em {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
+ Por exemplo: as permissões de internet e despertador estão em {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}. Portanto,
+ as permissões são concedidas automaticamente no tempo de instalação.
+ </p>
+
+ <p>O sistema pode também conceder as permissões de sistema e assinatura de aplicativo,
+ como descrito em <a href="#system-apps">permissões de assinatura
+ e aplicativos do sistema</a>. O usuário <em>não</em> é alertado a conceder permissões
+ no tempo de instalação.</p>
+ </li>
+
+ <li>
+ <strong>O usuário concede permissões no tempo de execução:</strong> Quando um aplicativo solicita
+ uma permissão, o sistema exibe um diálogo ao usuário e, em seguida,
+ chama a função de retorno de chamada do aplicativo para notificá-lo se a permissão foi concedida. Se um
+ usuário concede uma permissão, o aplicativo recebe todas
+ as permissões na área funcional desta permissão que foram declaradas no manifesto do aplicativo.
+ </li>
+
+</ul>
+
+<p>
+ Este modelo de permissões altera a forma como o aplicativo se comporta diante os recursos
+ que precisam de permissões. Eis um resumo das práticas de desenvolvimento que devem
+ ser seguidas para ajustar para este modelo:
+</p>
+
+<ul>
+
+ <li>
+ <strong>Sempre verificar as permissões:</strong> Quando o aplicativo
+ precisa realizar uma ação que requer uma permissão, ele deve primeiro verificar
+ se já a tem. Caso não tenha, ele solicita
+ o concedimento desta permissão.
+ </li>
+
+ <li>
+ <strong>Lidar com falta de permissões dignamente:</strong> Se o aplicativo não
+ recebe a permissão adequada, ele deve lidar com a falha de forma limpa.
+ Por exemplo, se a permissão é necessária para um recurso adicionado,
+ o aplicativo pode desativar este recurso. Se a permissão for essencial
+ para que o aplicativo funcione, ele desativará toda sua funcionalidade
+ e informará ao usuário que precisa desta permissão.
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>Figura 1.</strong> Tela de permissões nas configurações do aplicativo.
+ </p>
+ </div>
+
+ <li>
+ <strong>As permissões são revogáveis:</strong> Os usuários podem revogar as permissões
+ de um aplicativo a qualquer momento. Se um usuário desativar as permissões de um aplicativo,
+ o aplicativo <em>não</em> é notificado. Novamente, o aplicativo deve verificar
+ se tem todas as permissões necessárias antes de realizar qualquer ação restrita.
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Observação:</strong> se um aplicativo direcionar o M Developer Preview, ele
+ <em>deve</em> usar o novo modelo de permissões.
+</p>
+
+<p>
+ No momento do lançamento do M Developer Preview,
+ nem todos os aplicativos Google implementam completamente o novo modelo de permissões. A Google está atualizando estes aplicativos
+ durante o curso do M Developer Preview para respeitar adequadamente a configuração
+ de alternação de permissões.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> se o aplicativo tiver a própria superfície de API,
+ não represente permissões sem antes garantir que o autor da chamada tenha as permissões necessárias
+ para acessar esses dados.
+</p>
+
+<h3 id="system-apps">
+ Permissões de assinatura e aplicativos do sistema
+</h3>
+
+<p>
+ Geralmente, quando um usuário instala um aplicativo, o sistema somente fornece ao aplicativo o
+ {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL}. No entanto, sob algumas circunstâncias, o sistema concede
+ ao aplicativo mais permissões:
+</p>
+
+<ul>
+ <li>Se um aplicativo faz parte da imagem do sistema, ele recebe automaticamente
+ todas as permissões listadas no manifesto.
+ </li>
+
+ <li>Se o aplicativo solicitar as permissões no manifesto que está em {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE},
+ e estiver assinado com o mesmo certificado que o aplicativo que declarou essas permissões,
+ o sistema concederá essas permissões na instalação ao aplicativo
+ que fez a solicitação.
+ </li>
+</ul>
+
+<p>
+ Em ambos os casos, o usuário ainda pode revogar as permissões a qualquer
+ momento acessando a tela de <strong>configurações</strong> do sistema e escolhendo <strong>Aplicativos
+ ></strong> <i>app_name</i> <strong>> Permissões</strong>. O aplicativo
+ deve continuar com a verificação das permissões no tempo de execução e solicitá-las
+ se necessário.
+</p>
+
+<h3 id="compatibility">
+ Compatibilidade anterior e posterior
+</h3>
+
+<p>
+ Se um aplicativo não direciona para o M Developer Preview, ele deve continuar a usar
+ o modelo antigo de permissões mesmo nos dispositivos M Preview. Quando o usuário instala
+ o aplicativo, o sistema pede para que ele conceda todas as permissões
+ listadas no manifesto do aplicativo.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> em dispositivos que são executados no M Developer Preview,
+ um usuário pode desativar as permissões para qualquer aplicativo (incluindo aplicativos de legado)
+ na tela de configurações do aplicativo. Se um usuário desativa as permissões de um aplicativo de legado, o sistema
+ silenciosamente desativa a funcionalidade adequada. Quando um aplicativo tentar realizar
+ uma operação que requer esta permissão, a operação não necessariamente causará
+ uma exceção. Em vez disso, ele retornará um conjunto de dados vazio,
+ sinalizará um erro ou exibirá um comportamento inesperado. Por exemplo, caso queira
+ consultar um calendário sem permissão, o método retorna um conjunto de dados vazio.
+</p>
+
+<p>
+ Se instalar um aplicativo usando o novo modelo de permissões em um dispositivo
+ que não está executando o M Preview,
+ o sistema o tratará da mesma forma que qualquer outro aplicativo: o sistema pedirá
+ para que o usuário conceda todas as permissões declaradas no momento da instalação.
+</p>
+
+<p class="note">
+ <strong>Observação:</strong> para a liberação de prévia, deve-se definir a versão mínima de SDK
+ para o M Preview SDK para compilar com o SDK de prévia. Isto significa que você
+ não poderá testar tais aplicativos em plataformas mais antigas durante a prévia
+ de desenvolvedor.
+</p>
+
+<h3 id="perms-vs-intents">Permissões versus intenções</h3>
+
+<p>
+ Em vários casos, é possível escolher entre duas maneiras para que o aplicativo realize
+ uma tarefa. É possível fazer com que o aplicativo solicite uma permissão para realizar a operação
+ por conta própria. Alternativamente, é possível fazer com que o aplicativo use uma intenção para que outro aplicativo
+ realize a tarefa.
+</p>
+
+<p>
+ Por exemplo, imagine que o aplicativo precisa da função de tirar fotos com
+ a câmera do dispositivo. O aplicativo pode solicitar a permissão
+<code>android.permission.CAMERA</code>, que permite que ele acesse
+ a câmera diretamente. O aplicativo então usará as APIs da câmera
+ para controlar a câmera e tirar uma foto. Esta abordagem fornece ao aplicativo
+ controle completo sobre o processo de fotografia e permite
+ que você incorpore a IU da câmera.
+</p>
+
+<p>
+ No entanto, caso não precise de tal controle, é possível apenas usar uma intenção {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE}
+ para solicitar uma imagem. Ao iniciar a intenção, o usuário deve escolher
+ um aplicativo de câmera (se não houver um aplicativo padrão de câmera)
+ para tirar a foto. O aplicativo da câmera retorna a imagem ao método {@link
+ android.app.Activity#onActivityResult onActivityResult()} do aplicativo.
+</p>
+
+<p>
+ De forma semelhante, caso precise realizar uma ligação,
+ acessar os contatos do usuário etc., é possível fazer estas ações criando uma intenção adequada
+ ou solicitar a permissão e o acesso aos objetos adequados diretamente. Essas são
+ as vantagens e desvantagens de cada abordagem.
+</p>
+
+<p>
+ Se usar permissões:
+</p>
+
+<ul>
+ <li>O aplicativo tem controle completo sobre a experiência do usuário ao realizar
+ a operação. No entanto, esse controle amplo é adicionado à complexidade da tarefa,
+ levando em consideração a necessidade de projetar uma IU adequada.
+ </li>
+
+ <li>O usuário deve fornecer a permissão uma vez: na primeira realização
+ da operação. Depois, o aplicativo pode realizar a operação sem
+ precisar de mais interações do usuário. No entanto,
+ se o usuário não conceder a permissão (ou revogá-la posteriormente),
+ o aplicativo não conseguirá realizar a operação.
+ </li>
+</ul>
+
+<p>
+ Se usar uma intenção:
+</p>
+
+<ul>
+ <li>Você não terá que projetar a IU para a operação. O aplicativo que lida com
+ a intenção fornece a IU. No entanto, isso significa que você não terá controle
+ completo sobre a experiência de usuário. O usuário poderá interagir com um aplicativo
+ que você nunca viu.
+ </li>
+
+ <li>Se o usuário não tem um aplicativo padrão para a operação,
+ o sistema pede para que o usuário escolha um aplicativo.
+ Se o usuário não designar um manipulador padrão,
+ ele terá que acessar uma caixa de diálogo extra sempre que realizar a operação.
+ </li>
+</ul>
+
+<h2 id="coding">Codificação para permissões de tempo de execução</h2>
+
+<p>
+ Se um aplicativo direciona o novo M Developer Preview, ele deve usar o novo
+ modelo de permissões. Isto significa que, além de declarar as permissões necessárias no manifesto,
+ deve-se também verificar se o aplicativo
+ tem as permissões no tempo de execução e,
+ caso ainda não as tenha, solicitá-las.
+</p>
+
+<h3 id="enabling">
+ Possibilitar um novo modelo de permissões
+</h3>
+
+<p>
+ Para possibilitar o modelo de permissões do M Developer Preview, configure o atributo
+<code>targetSdkVersion</code> do aplicativo para <code>"MNC"</code> e
+<code>compileSdkVersion</code> para <code>"android-MNC"</code>. Isto ativará
+ todos os novos recursos de permissão.
+</p>
+
+<p>
+ Para a liberação de uma prévia, deve-se definir <code>minSdkVersion</code> para
+<code>"MNC"</code> para compilar com o SDK de prévia.
+</p>
+
+<h3 id="m-only-perm">
+ Designar uma permissão somente para o M Preview
+</h3>
+
+<p>
+ É possível usar o novo elemento <code><uses-permission-sdk-m></code> no manifesto do aplicativo
+ para indicar que uma permissão é necessária apenas no M Developer Preview. Se você
+ declarar uma permissão desta maneira, sempre que o aplicativo for instalado
+ em um dispositivo mais antigo, o sistema não solicitará ao usuário
+ nem concederá a permissão ao aplicativo. Usando o elemento <code><uses-permission-sdk-m></code>
+, é possível adicionar novas permissões
+ a versões atualizadas do aplicativo sem forçar os usuários a conceder permissões
+ ao instalar a atualização.
+</p>
+
+<p>
+ Se o aplicativo está sendo executado em um dispositivo com M Developer Preview, o
+<code><uses-permission-sdk-m></code> se comporta da mesma forma que
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
+ O sistema não solicita ao usuário que conceda quaisquer permissões ao instalar o aplicativo
+ e o aplicativo solicita as permissões à medida que forem necessárias.
+</p>
+
+<h3 id="prompting">
+ Solicitação de permissões
+</h3>
+
+<p>
+ Se o aplicativo usa o novo modelo de permissões do M Developer Preview,
+ o usuário não recebe solicitações para conceder todas as permissões quando o aplicativo é iniciado pela primeira vez em um dispositivo
+ que está sendo executado no M Preview. Em vez disso, o aplicativo solicita as permissões à medida
+ que forem necessárias. Quando um aplicativo solicita uma permissão, o sistema exibe uma caixa de diálogo
+ ao usuário.
+</p>
+
+<p>
+ Se o aplicativo executar em um dispositivo que tem SDK 22 ou inferior,
+ ele usará o antigo modelo de permissões. Quando o usuário instala o aplicativo, ele é solicitado a conceder
+ todas as permissões que o aplicativo lista no manifesto,
+ exceto as permissões que forem marcadas com <code><uses-permission-sdk-m></code>.
+</p>
+
+<h4 id="check-platform">Verifique em qual plataforma o aplicativo está sendo executado</h4>
+
+<p>
+ Este modelo de permissões é suportado apenas em dispositivos que estão executando
+ o M Developer Preview. Antes de chamar qualquer um destes métodos,
+ o aplicativo deve verificar em qual plataforma está sendo executado
+ verificando o valor de {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME}. Se o dispositivo estiver sendo executado no M Developer Preview,
+ {@link android.os.Build.VERSION#CODENAME CODENAME} será <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Verifique se o aplicativo tem a permissão necessária</h4>
+
+<p>Quando o usuário tenta fazer algo que requer uma permissão,
+ o aplicativo verifica se tem a permissão para realizar esta operação. Para fazer isto,
+ o aplicativo chama
+ <code>Context.checkSelfPermission(<i>permission_name</i>)</code>. O aplicativo
+ deve realizar isto para verificar se sabe que o usuário já concedeu esta permissão,
+ levando em consideração que o usuário pode revogar
+ as permissões do aplicativo a qualquer momento. Por exemplo,
+ se um usuário quiser usar um aplicativo para tirar uma foto, o aplicativo chamará
+ <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>Tabela 1.</strong> Permissões e grupos de permissões.</p>
+<table>
+ <tr>
+ <th scope="col">Grupo de permissões</th>
+ <th scope="col">Permissões</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">Solicitar permissões se necessário</h4>
+
+<p>Se o aplicativo já não tem a permissão necessária, ele chama o método
+ <code>Activity.requestPermissions(String[], int)</code> para solicitar
+ as permissões necessárias. O aplicativo passa
+ as permissões que deseja e também um "código de solicitação" do inteiro.
+ Este método funciona de forma assíncrona: ele retorna imediatamente e,
+ depois que o usuário responde à caixa de diálogo, o sistema chama
+ o método de retorno de chamada do aplicativo com os resultados, passando o mesmo "código de solicitação" que o aplicativo passou
+ para <code>requestPermissions()</code>.</p>
+
+ <p>O seguinte código verifica se o aplicativo tem a permissão
+ para ler os contatos do usuário e solicita a permissão, se necessário:</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">Lidar com a resposta de solicitação das permissões</h4>
+
+<p>
+ Quando um aplicativo solicita as permissões, o sistema apresenta uma caixa de diálogo
+ ao usuário. Quando o usuário responde, o sistema invoca o
+ <code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+ do aplicativo, passando a ele a resposta do usuário. O aplicativo precisa substituir este método. O retorno de chamada
+ recebe o mesmo código de solicitação passado para
+ <code>requestPermissions()</code>. Por exemplo, se um aplicativo solicita o acesso
+ <code>READ_CONTACTS</code>, ele pode ter o seguinte
+ método de retorno de chamada:
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>Se o usuário concede a permissão, o sistema fornece ao aplicativo todas as permissões
+ que o manifesto do aplicativo lista para esta área funcional. Se o usuário negar a solicitação,
+ deve-se tomar a ação adequada. Por exemplo, deve-se desativar
+ quaisquer ações de menu que dependam desta permissão.
+ </li>
+</p>
+
+<p>
+ Quando o sistema pede para que o usuário conceda uma permissão, esse usuário tem a opção
+ de dizer ao sistema para que não peça esta permissão novamente. Nesse caso,
+ quando um aplicativo usa <code>requestPermissions()</code> para solicitar esta permissão,
+ o sistema nega imediatamente. Neste caso, o sistema chama
+ <code>onRequestPermissionsResult()</code> da mesma forma que faria se o usuário tivesse
+ rejeitado explicitamente a solicitação novamente. Por este motivo, o aplicativo
+ não pode presumir que uma interação direta com o usuário ocorreu.
+</p>
+
+<h2 id="testing">Teste de permissões de tempo de execução</h2>
+
+
+<p>
+ Se o aplicativo for direcionado para o M Developer Preview, deve-se testar
+ se ele lida com as permissões corretamente. Não se pode presumir que o aplicativo
+ terá qualquer permissão quando executado. Quando o aplicativo é iniciado pela primeira vez,
+ é provável que não tenha permissões. O usuário pode revogar e restaurar permissões
+ a qualquer momento.
+</p>
+
+<p>
+ Deve-se testar o aplicativo para garantir que ele se comporte corretamente em todas
+ as situações de permissão. Com o M Preview SDK, fornecemos os novos comandos
+ de <a href="{@docRoot}tools/help/adb.html">Android
+ Debug Bridge (adb)</a> para possibilitar que o aplicativo seja testado com quaisquer
+ configurações de permissões necessárias.
+</p>
+
+<h3>
+ Novas opções e comandos adb
+</h3>
+
+<p>
+ As ferramentas da plataforma M Preview SDK fornecem vários comandos novos para permitir
+ que você teste como o aplicativo lida com permissões.
+</p>
+
+<h4>
+ Instalar com permissões
+</h4>
+
+<p>
+ É possível usar a nova opção <code>-g</code> do comando <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, que instala o aplicativo
+ e fornece todas as permissões listadas em seu manifesto:
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ Conceder e revogar permissões
+</h4>
+
+<p>
+ É possível usar os novos comandos do <a href="{@docRoot}tools/help/adb.html#pm">gerenciador
+ de pacotes (pm)</a> de ADB para conceder e revogar as permissões de um aplicativo instalado.
+ Esta funcionalidade pode ser útil para testes automatizados.
+</p>
+
+<p>
+ Para conceder uma permissão, use o comando <code>grant</code> do gerenciador de pacote:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ Por exemplo: para conceder a permissão do pacote com.example.myapp para gravar áudios,
+ use este comando:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ Para revogar uma permissão, use o comando <code>revoke</code> do gerenciador de pacote:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">Práticas recomendadas</h2>
+
+<p>
+ O novo modelo de permissões fornece aos usuários uma experiência mais suave
+ e facilita a instalação de aplicativos, deixando-os mais confortáveis
+ com o que os aplicativos estão fazendo. Sugerimos que você siga as práticas recomendadas para aproveitar
+ todas as vantagens do novo modelo.
+</p>
+
+
+<h3 id="bp-what-you-need">Peça somente as permissões necessárias</h3>
+
+<p>
+ Sempre que você pede uma permissão, o usuário é forçado a tomar uma decisão.
+ Se o usuário negar a solicitação, a funcionalidade do aplicativo será reduzida.
+ Deve-se minimizar o número de solicitações realizadas.
+</p>
+
+<p>
+ Por exemplo: o aplicativo pode frequentemente adquirir a funcionalidade necessária usando
+ uma <a href="{@docRoot}guide/components/intents-filters.html">intenção</a> em vez
+ de solicitar permissões. Se o aplicativo precisa tirar fotos com a câmera do telefone,
+ é possível usar uma intenção {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE}. Quando o aplicativo executa a intenção,
+ o sistema pede para que o usuário escolha um aplicativo de câmera já instalado
+ para tirar a foto.
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ Não oprima o usuário
+</h3>
+
+<p>
+ Se você confrontar o usuário com várias solicitações de permissão de uma só vez,
+ é possível que ele se sinta oprimido e saia do aplicativo.
+ Em vez disso, deve-se solicitar as permissões somente quando necessário.
+</p>
+
+<p>
+ Em alguns casos, uma ou mais permissões podem ser absolutamente essenciais para o aplicativo.
+ Nesta situação, faz sentido solicitar todas as permissões assim
+ que o aplicativo é iniciado. Por exemplo: se você fizer um aplicativo de fotografia,
+ ele precisará de acesso à câmera do dispositivo. Quando o usuário iniciar o aplicativo
+ pela primeira vez, ele não se surpreenderá quando receber
+ uma solicitação de permissão para usar a câmera. Mas, se o mesmo aplicativo tiver um recurso
+ para compartilhar fotos com os contatos do usuário, <em>não</em> se deve
+ pedir esta permissão na primeira inicialização. Em vez disso, espere o usuário tentar usar
+ o recurso de compartilhamento para pedir a permissão.
+</p>
+
+<p>
+ Se o aplicativo fornecer um tutorial, faz sentido solicitar as permissões
+ necessárias no final da sequência do tutorial.
+</p>
+
+<h3 id="bp-explain">
+ Explique o porquê da necessidade das permissões
+</h3>
+
+<p>
+ O diálogo de permissões exibido pelo sistema ao chamar
+ <code>requestPermissions()</code> diz quais permissões o aplicativo requer,
+ mas não diz o porquê. Em alguns casos, o usuário pode achar isto confuso.
+ É uma boa ideia explicar ao usuário o porquê da necessidade das permissões
+ para o aplicativo antes de chamar <code>requestPermissions()</code>.
+</p>
+
+<p>
+ Por exemplo: um aplicativo de fotografia pode precisar usar serviços de localização
+ para poder marcar as fotos geograficamente. Um usuário normal pode não entender que uma foto
+ pode conter informações de localização e ficar confuso quando
+ o aplicativo de fotografia quiser saber a localização. Portanto, neste caso, é uma boa ideia o aplicativo explicar
+ ao usuário sobre este recurso <em>antes</em> de chamar
+ <code>requestPermissions()</code>.
+</p>
+
+<p>
+ Uma maneira de fazer isto é incorporar estas solicitações em um tutorial do aplicativo. O tutorial pode exibir cada um dos recursos
+ do aplicativo e, à medida que fizer isto,
+ pode também explicar quais permissões são necessárias. Por exemplo, o tutorial do aplicativo de fotografia
+ pode demonstrar os recursos de compartilhamento de fotos com os contatos e,
+ em seguida, dizer ao usuário que ele precisa fornecer as permissões
+ para que o aplicativo possa visualizar os contatos. O aplicativo pode então chamar <code>requestPermissions()</code> para solicitar
+ ao usuário este acesso. É claro que nem todos os usuários seguirão o tutorial.
+ Portanto, ainda é necessário verificar e solicitar as permissões durante
+ a operação normal do aplicativo.
+</p>
diff --git a/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png
new file mode 100644
index 0000000..a53a33e
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png
new file mode 100644
index 0000000..87816ff
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/direct-share-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png
new file mode 100644
index 0000000..77f9982
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png
new file mode 100644
index 0000000..4749bcf
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/fingerprint-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png
new file mode 100644
index 0000000..724a6af
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline-crop.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png
new file mode 100644
index 0000000..e9a339e
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/m-preview-timeline.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png b/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png
new file mode 100644
index 0000000..87d1cfc
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/perf-test-frame-latency.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png b/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png
new file mode 100644
index 0000000..589a923
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/perf-test-framestats.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/text-selection.gif b/docs/html-intl/intl/pt-br/preview/images/text-selection.gif
new file mode 100644
index 0000000..1d82fc6
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/text-selection.gif
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png
new file mode 100644
index 0000000..c3e4e44
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png
new file mode 100644
index 0000000..5dcf610
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/images/work-profile-screen_2x.png
Binary files differ
diff --git a/docs/html-intl/intl/pt-br/preview/overview.jd b/docs/html-intl/intl/pt-br/preview/overview.jd
new file mode 100644
index 0000000..ce5a596
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Visão geral do programa
+page.metaDescription=Boas-vindas ao Android M Developer Preview, um programa que fornece tudo que é necessário para testar e otimizar os aplicativos para a próxima versão do Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Boas-vindas ao <strong>Android M Developer Preview</strong>, um programa que fornece
+ tudo que é necessário para testar e otimizar os aplicativos para a próxima versão
+ do Android. É de graça e você pode começar agora mesmo: basta fazer
+ o download das ferramentas M Developer Preview.
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ Imagens de sistema de emulador e hardware
+ </h5>
+
+ <p>
+ Execute e teste os aplicativos no Nexus 5, 6, 9 e Player (para TV), bem como
+ em emuladores.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Código de plataforma mais recente
+ </h5>
+
+ <p>
+ Nós forneceremos várias atualizações durante a prévia. Portanto, você
+ testará de acordo com as alterações mais recentes da plataforma.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Atualizações entregues por OTA
+ </h5>
+
+ <p>
+ É possível obter atualizações por OTA (over-the-air) ao programar o dispositivo
+ em flash para a prévia inicial.
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Novos comportamentos e capacidades
+ </h5>
+
+ <p>
+ Inicie o trabalho cedo para suportar os novos comportamentos da plataforma,
+ como novo modelo de permissões de tempo de execução e recursos de economia de energia.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Janela de prioridades para problemas informados por desenvolvedores
+ </h5>
+
+ <p>
+ Durante as primeiras semanas, nós daremos prioridade aos problemas informados
+ por desenvolvedores. Portanto, teste e forneça-nos feedback o quanto antes.
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Feedback e suporte
+ </h5>
+
+ <p>
+ Informe problemas e dê-nos feedback usando o <a href="https://code.google.com/p/android-developer-preview/">issue tracker</a>.
+ Conecte-se a outros desenvolvedores na <a href="http://g.co/dev/AndroidMDevPreview">Comunidade M Developer</a>.
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ Linha do tempo e atualizações
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ O M Developer Preview estará em execução de 28 de maio até o Android M SDK final, que
+ disponibilizaremos brevemente antes do lançamento público durante
+ o 3º trimestre de 2015.
+</p>
+
+<p>
+ Nos marcos de desenvolvimento principais, entregamos atualizações para os dispositivos de teste.
+ Os marcos de experiência são
+</p>
+
+<ul>
+ <li>
+ <strong>Preview 1</strong> (lançamento inicial do Preview, final de maio),
+ </li>
+
+ <li>
+ <strong>Preview 2</strong> (final de junho/início de julho) e
+ </li>
+
+ <li>
+ <strong>Preview 3</strong> (próximo ao final de julho)
+ </li>
+</ul>
+
+<p>
+ Estas atualizações culminam no <strong>SDK final</strong> (no 3º trimestre),
+ que fornecerá APIs oficiais para a nova versão do Android,
+ bem como os recursos e comportamentos do sistema final.
+</p>
+
+<p>
+ Ao testar e desenvolver no Android M, recomendamos que você <strong>mantenha
+ o ambiente de desenvolvimento atualizado</strong> à medida que atualizações do Preview são lançadas.
+ Para facilitar o processo, fornecemos <strong>atualizações "over-the-air"
+ (OTA)</strong> aos dispositivos já programados em flash para uma versão do Preview, além
+ de fornecemos imagens do sistema que estão disponíveis para download e programação em flash manualmente.
+</p>
+<p class="note">
+ <strong>Observação:</strong> as imagens do sistema e o SDK final não podem ser entregues
+ por OTA. Em vez disso, precisarão ser <strong>programadas em flash manualmente</strong> para
+ os dispositivos de teste.</strong>
+</p>
+
+<p>
+ Notificaremos você quando as atualizações do Preview estiverem disponíveis por meio do <a href="http://android-developers.blogspot.com/">Blogue de desenvolvedores do Android</a>, além
+ deste site
+ e da <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M Developer</a>.
+</p>
+
+<h2 id="preview_tools">
+ O que há no Preview?
+</h2>
+
+<p>
+ O M Developer Preview inclui tudo que é necessário para testar os aplicativos existentes
+ em uma variedade de tamanhos de tela, tecnologias de rede, chipsets de CPU/GPU
+ e arquiteturas de hardware.
+</p>
+
+<h4>
+ Ferramentas SDK
+</h4>
+
+<p>
+ É possível fazer o download destes componentes pelo SDK Manager no <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>:
+</p>
+
+<ul>
+ <li>M Developer Preview <strong>ferramentas SDK</strong>
+ </li>
+
+ <li>M Developer Preview <strong>imagem do sistema de emulador</strong> (32 bits
+e 64 bits)
+ </li>
+
+ <li>M Developer Preview <strong>imagem do sistema de emulador para Android TV</strong>
+ (32 bits)
+ </li>
+</ul>
+
+<h4>
+ Imagens do sistema de hardware
+</h4>
+
+<p>
+ É possível fazer o download destas imagens de sistema de hardware para dispositivos Nexus a partir
+ da <a href="download.html">página de download</a>:
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE) imagem do sistema de dispositivo “hammerhead”
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> imagem do sistema de dispositivo “shamu”
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi) imagem do sistema de dispositivo “volantis”
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV) imagem do sistema de dispositivo “fugu”
+ </li>
+</ul>
+
+<h4>
+ Exemplo de código e documentação
+</h4>
+
+<p>
+ Estes recursos de documentação ajudam você a aprender sobre o Preview:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">Configuração do SDK</a> tem instruções passo a passo
+ para você começar.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Guia de teste</a> e <a href="behavior-changes.html">Mudanças de comportamento</a> mostram as áreas essenciais para o teste.
+ </li>
+
+ <li>Documentação de novas APIs, incluindo uma <a href="api-overview.html">Visão geral das APIs</a>,
+ <a href="{@docRoot}preview/download.html#docs">Referência da API</a> disponível para download e guias de desenvolvedor detalhados sobre
+ os recursos principais, como
+ <a href="{@docRoot}preview/features/runtime-permissions.html">permissões</a>,
+ <a href="{@docRoot}preview/backup/index.html">backup de aplicativo</a> etc.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">Exemplo de código</a> que demonstra como suportar
+ permissões e outros novos recursos.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">Notas de versão</a> para a versão atual do
+ M Developer Preview, incluindo notas de mudanças e relatórios de diferença.
+ </li>
+</ul>
+
+<h4>
+ Recursos de suporte
+</h4>
+
+<p>
+ Use estes recursos de suporte ao testar e desenvolver no
+ M Developer Preview:
+</p>
+
+<ul>
+ <li>O <a href="https://code.google.com/p/android-developer-preview/">Issue Tracker do M
+ Developer Preview</a> é o <strong>canal principal
+ de feedback.</strong> É possível informar erros, problemas de desempenho e feedback
+ geral pelo issue tracker. Também é possível verificar os <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">erros conhecidos</a>
+ e encontrar etapas de resolução.
+ </li>
+
+ <li>A <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M Developer
+</a> é uma comunidade do Google+ onde é possível <strong>se conectar
+ a outros desenvolvedores</strong> que trabalham com o Android M. É possível compartilhar
+ observações ou ideias, além de encontrar respostas para as dúvidas sobre o Android M.
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Destinação, APIs de prévia e publicação
+</h2>
+
+<p>
+ O Android M Developer Preview é uma versão apenas para desenvolvimento
+ e <strong>não possui um nível da API padrão</strong>. Caso opte
+ pelos comportamentos de compatibilidade para testar o aplicativo (o que é muito recomendado),
+ é possível destinar o M Developer Preview configurando o <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+ do aplicativo para <code>“MNC”</code>.
+</p>
+
+<p>
+ O Android M Developer Preview fornece <strong>APIs de prévia</strong>
+ — as APIs não serão oficiais até o lançamento do SDK final,
+ atualmente planejado para o terceiro trimestre de 2015. Isto significa que é possível
+ <strong>esperar alterações secundárias de APIs</strong> com o tempo, especialmente
+ durante as semanas iniciais do programa. Forneceremos um resumo das alterações
+ com cada atualização do Android M Developer Preview.
+</p>
+
+<p class="note">
+ Observe que, apesar das APIs da prévia poderem ser alteradas, os comportamentos essenciais do sistema,
+ como permissões de tempo de execução e recursos de economia de energia, são estáveis e estão prontos
+ para serem testados.
+</p>
+
+<p>
+ Em termos de publicação, o Google Play <strong>evita a publicação de aplicativos
+ destinados para o M Developer Preview</strong>. Quando o SDK final do Android M estiver
+ disponível, você poderá destinar o nível da API do Android M oficial
+ e publicar o aplicativo no Google Play. Enquanto isso, caso queira distribuir um aplicativo
+ destinado para Android M para testadores, é possível fazê-lo por e-mail ou por download direto
+ a partir do site.
+</p>
+
+<h2 id="get_started">
+ Como começar
+</h2>
+
+<p>
+ Para começar o teste do aplicativo:
+</p>
+
+<ol>
+ <li>Revise a <a href="{@docRoot}preview/api-overview.html">Visão geral da API</a>
+ e as <a href="{@docRoot}preview/behavior-changes.html">Mudanças de comportamento</a> para
+ ter uma ideia do que há de novo e como isto afeta os aplicativos. Em particular, aprenda mais sobre
+ o novo modelo<a href="{@docRoot}preview/features/runtime-permissions.html">de permissões
+ de tempo de execução</a>, recursos de economia de energia e backup automático.
+ </li>
+
+ <li>Configure o ambiente seguindo as instruções para
+ <a href="{@docRoot}preview/setup-sdk.html">Configurar o Preview SDK</a>
+ e ajustar os dispositivos de teste.
+ </li>
+
+ <li>Siga <a href="https://developers.google.com/android/nexus/images">
+ as instruções de programação em flash</a> para programar em flash a imagem do sistema do M Developer Preview mais recente
+ para Nexus 5, 6, 9 e Player. Após programar em flash o dispositivo de desenvolvimento,
+ as atualizações do Preview serão entregues por atualizações OTA (over-the-air).</a>
+ </li>
+
+ <li>Faça o download da <a href="{@docRoot}preview/download.html#docs">Referência da API do
+ M Preview</a> e dos <a href="{@docRoot}preview/samples.html">exemplos do M Preview
+</a> para obter mais informações sobre os novos recursos de API e como usá-los
+ no aplicativo.
+ </li>
+
+ <li>Junte-se à <a href="http://g.co/dev/AndroidMDevPreview">Comunidade Android M
+ Developer</a> para obter as notícias mais recentes e conecte-se a outros
+ desenvolvedores que trabalham com a nova plataforma.
+ </li>
+</ol>
+
+<p>
+ Agradecemos a sua participação no programa M Developer Preview do Android!
+</p>
diff --git a/docs/html-intl/intl/ru/preview/api-overview.jd b/docs/html-intl/intl/ru/preview/api-overview.jd
new file mode 100644
index 0000000..ae30e09
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=Обзор API-интерфейсов
+page.keywords=предварительная версия,пакет sdk,совместимость
+page.tags=previewresources, androidm
+sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Содержание
+<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">развернуть</span>
+ <span class="less" style="display:none">свернуть</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">Связывание приложений</a></li>
+ <li><a href="#backup">Автоматическое резервное копирование для приложений</a></li>
+ <li><a href="#authentication">Авторизация</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">Авторизация по отпечатку пальца</a></li>
+ <li><a href="#confirm-credential">Подтверждение учетных данных</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">Прямой обмен контентом</a></li>
+ <li><a href="#voice-interactions">Голосовой интерфейс</a></li>
+ <li><a href="#assist">API-интерфейс помощника</a></li>
+ <li><a href="#notifications">Уведомления</a></li>
+ <li><a href="#bluetooth-stylus">Поддержка пера Bluetooth</a></li>
+ <li><a href="#ble-scanning">Улучшенное сканирование Bluetooth с низким потреблением энергии</a></li>
+ <li><a href="#hotspot">Поддержка Hotspot 2.0, выпуск 1</a></li>
+ <li><a href="#4K-display">Режим отображения в формате 4K</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">Метод ColorStateLists для работы с темами</a></li>
+ <li><a href="#audio">Работа с аудио</a></li>
+ <li><a href="#video">Работа с видео</a></li>
+ <li><a href="#camera">Возможности камеры</a>
+ <ol>
+ <li><a href="#flashlight">API-интерфейс вспышки</a></li>
+ <li><a href="#reprocessing">Повторная обработка изображения с камеры</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Возможности Android for Work</a></li>
+</ol>
+
+<h2>Различия между API-интерфейсами</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API уровня 22 в M Preview »</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M Developer Preview — ознакомительная версия предстоящего выпуска платформы Android,
+в котором реализованы новые возможности как для пользователей, так и для
+разработчиков приложений. В этой статье мы расскажем о наиболее интересных API-интерфейсах.</p>
+
+<p>Версия M Developer Preview предназначена для тех, <strong>кто хочет первым ознакомиться с новой платформой</strong>,
+а также для <strong>тестировщиков</strong>. <a href="{@docRoot}preview/setup-sdk.html">M Developer Preview — прекрасная возможность
+</a>повлиять на вектор развития
+платформы Android.
+Мы с нетерпением ждем ваших отзывов!</p>
+
+<p class="caution"><strong>Внимание!</strong> Не публикуйте в магазине Google Play приложения,
+предназначенные для M Developer Preview.</p>
+
+<p class="note"><strong>Примечание.</strong> В этой статье часто упоминаются классы и методы,
+для которых на сайте <a href="{@docRoot}">developer.android.com</a> пока еще нет справочных материалов. Такие элементы API-интерфейса обозначаются здесь следующим образом:
+{@code code style} (без гиперссылок). Чтобы ознакомиться с предварительной документацией по этим элементам,
+загрузите <a href="{@docRoot}preview/download.html#docs">справочное руководство по предварительной версии</a>.</p>
+
+<h3>Важные изменения в работе приложений</h3>
+
+<p>Если вы ранее публиковали приложения для Android, то примите во внимание, что изменения в платформе могут повлиять
+на работу опубликованных приложений.</p>
+
+<p>Подробные сведения представлены в статье <a href="behavior-changes.html">Изменения в работе</a>.</p>
+
+<h2 id="app-linking">Связывание приложений</h2>
+<p>В M Preview улучшена система намерений Android за счет более эффективного связывания приложений.
+Теперь у вас есть возможность связывать приложения с вашими собственными веб-доменами. Благодаря этому
+платформа может сама, без вмешательства пользователя, определить приложение, которое будет использоваться по умолчанию
+для обработки определенной веб-ссылки. О том, как реализовать такую возможность, можно почитать в статье
+<a href="{@docRoot}preview/features/app-linking.html">Связывание приложений</a>.
+
+<h2 id="backup">Автоматическое резервное копирование для приложений</h2>
+<p>Теперь система автоматически выполняет полное резервное копирование и восстановление данных ваших приложений. Для приложений,
+написанных под M Preview, эта функция включена по умолчанию — вам даже не нужно добавлять отдельный код. Если пользователь решит удалить свою учетную запись Google, все резервные копии его данных также будут удалены.
+ О том, как работает эта функция и как настроить параметры резервного копирования элементов файловой системы,
+ рассказано в статье
+<a href="{@docRoot}preview/backup/index.html">Автоматическое резервное копирование для приложений</a>.</p>
+
+<h2 id="authentication">Авторизация</h2>
+<p>В M Preview представлены новые API-интерфейсы, которые позволяют авторизовать пользователей по отпечатку пальца
+(на устройствах, поддерживающих такую возможность), а также подтвердить учетные данные, если пользователь недавно авторизовался через механизмы разблокировки устройства
+(например, вводил пароль для разблокировки экрана). Эти API-интерфейсы рекомендуется использовать совместно с
+<a href="{@docRoot}training/articles/keystore.html">системой хранилища ключей Android</a>.</p>
+
+<h3 id="fingerprint-authentication">Авторизация по отпечатку пальца</h3>
+
+<p>Чтобы авторизовать пользователя по отпечатку пальца, получите экземпляр нового класса
+{@code android.hardware.fingerprint.FingerprintManager} и вызовите метод
+{@code FingerprintManager.authenticate()}. Эта функция доступна для совместимых
+устройств, оснащенных сканером отпечатков пальцев. Прежде всего, вам необходимо реализовать в своем приложении пользовательский интерфейс проверки
+подлинности по отпечатку пальца, а также использовать для него стандартный значок отпечатка пальца Android.
+Этот значок ({@code c_fp_40px.png}) вы можете найти в
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">примере приложения</a>. При разработке нескольких приложений, использующих функцию авторизации по отпечатку пальца,
+помните, что каждое из них должно самостоятельно выполнять проверку подлинности.
+</p>
+
+<p>Чтобы реализовать эту функцию, сначала добавьте в файл манифеста разрешение {@code USE_FINGERPRINT}.
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>Пример такой проверки подлинности вы найдете в
+<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">примере
+диалогового окна авторизации по отпечатку пальца</a>.</p>
+
+<p>Если вы тестируете эту функцию, выполните следующие действия:</p>
+<ol>
+<li>Установите инструменты SDK Android (версию 24.3), если у вас их еще нет.</li>
+<li>Зарегистрируйте в эмуляторе новый отпечаток пальца (в разделе
+<strong>Настройки > Безопасность > Отпечаток пальца</strong>) и следуйте дальнейшим инструкциям.</li>
+<li>Воспользовавшись указанной ниже командой, сымитируйте в эмуляторе события касания для проверки отпечатка пальца.
+ С помощью этой же команды сымитируйте события касания для проверки отпечатка пальца на экране блокировки или в
+своем приложении.
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>В Windows, возможно, потребуется выполнить команду {@code telnet 127.0.0.1 <emulator-id>}, а затем
+{@code finger touch <finger_id>}.
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">Подтверждение учетных данных</h3>
+<p>Для авторизации пользователей ваше приложение может обратиться к сведениям о том, как давно они разблокировали свое устройство в последний раз. Эта функция
+избавляет пользователя от необходимости запоминать отдельные пароли для каждого приложения, а вас — от необходимости
+реализовывать собственный пользовательский интерфейс авторизации. В приложении эту функцию следует
+использовать совместно с реализацией открытого или секретного ключа для авторизации пользователей.</p>
+
+<p>Чтобы задать временя ожидания, в течение которого после успешной
+авторизации можно использовать ключ повторно, вызовите новый метод
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+при настройке {@link javax.crypto.KeyGenerator} или
+{@link java.security.KeyPairGenerator}. На сегодняшний день эта функция совместима с симметричными криптографическими
+операциями.</p>
+
+<p>Не стоит слишком часто отображать диалоговое окно повторной авторизации — ваше
+приложение должно сначала попробовать использовать криптографический объект и только потом, если окажется, что время ожидания истекло, обратиться к методу
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+для повторной авторизации пользователя.
+</p>
+
+<p>Как можно реализовать эту функцию, показано в
+<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">примерепроверки учетных данных</a>.
+</p>
+
+<h2 id="direct-share">Прямой обмен контентом</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>M Preview содержит API-интерфейсы для интуитивно понятного и быстрого обмена контентом между пользователями. Теперь вы можете
+определить <em>целевые объекты прямого обмена</em>, которые будут запускать определенную операцию в приложении
+и открываться в меню <em>Поделиться</em>. С помощью данной функции пользователи могут обмениваться контентом
+с целевыми объектами, такими как контакты, в других приложениях. Например, целевой объект прямого обмена может запустить операцию
+в другом приложении социальной сети, что позволит пользователю напрямую делиться контентом с другом
+или членами сообщества через это приложение.</p>
+
+<p>Чтобы включить использование целевых объектов прямого обмена, необходимо определить класс, который наследует класс
+{@code android.service.} <br>
+{@code chooser.ChooserTargetService}. Объявите
+{@code ChooserTargetService} в манифесте. В этом объявлении укажите разрешение
+{@code BIND_CHOOSER_TARGET_SERVICE} и фильтр намерений с помощью действия
+{@code SERVICE_INTERFACE}.</p>
+<p>В примере ниже показано, как объявить {@code ChooserTargetService}
+ в вашем манифесте.</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>Для каждого действия, которое необходимо сделать доступным для {@code ChooserTargetService}, добавьте в манифест вашего приложения элемент
+{@code <meta-data>} с именем
+{@code "android.service.chooser.chooser_target_service"}.
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">Голосовой интерфейс</h2>
+<p>
+В M Preview представлен новый голосовой API-интерфейс, который, наряду с
+<a href="https://developers.google.com/voice-actions/" class="external-link">голосовыми командами</a>,
+позволяет встраивать в приложение диалоговое голосовое взаимодействие. Вызовите метод
+{@code android.app.Activity.isVoiceInteraction()}, чтобы определить, была ли операция запущена
+в ответ на голосовую команду. Если это так, ваше приложение может использовать класс
+{@code android.app.VoiceInteractor}, чтобы получить голосовое подтверждение от пользователя, предложить ему список вариантов
+на выбор и многое другое. Подробнее о реализации голосовых команд можно почитать в
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">руководстве к голосовому интерфейсу</a>.
+</p>
+
+<h2 id="assist">API-интерфейс помощника</h2>
+<p>
+M Preview предлагает новый способ взаимодействия пользователей с приложением — взаимодействие посредством помощника. Для этого
+пользователю необходимо разришить помощнику использовать текущий контекст, после чего он сможет вызывать помощника
+в любом приложении, удерживая кнопку <strong>Домой</strong>.</p>
+<p>Разработчик может также запретить приложению сообщать помощнику текущий контекст. Для этого установите флаг
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE}. Кроме стандартного набора
+информации, который платформа передает помощнику, ваше приложение может сообщать ему дополнительные
+сведения посредством нового класса {@code android.app.Activity.AssistContent}.</p>
+
+<p>Чтобы предоставить помощнику дополнительный контекст из вашего приложения, выполните следующие действия:</p>
+
+<ol>
+<li>Реализуйте интерфейс {@link android.app.Application.OnProvideAssistDataListener}.</li>
+<li>Зарегистрируйте этот приемник с помощью
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
+<li>Для предоставления контекста, относящего к конкретной операции, переопределите метод обратного вызова
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()},
+а также, при желании, новый метод обратного вызова{@code Activity.onProvideAssistContent()}.
+</ol>
+
+<h2 id="notifications">Уведомления</h2>
+<p>В API-интерфейс уведомлений внесены следующие изменения:</p>
+<ul>
+ <li>{@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} — новый уровень фильтрации,
+соответствующий новому режиму «Не беспокоить» <em>Только будильник</em>.</li>
+ <li>{@code Notification.CATEGORY_REMINDER} — новое значение категории, позволяющее отличить
+установленные пользователем напоминания от других событий
+({@link android.app.Notification#CATEGORY_EVENT}) и будильников
+({@link android.app.Notification#CATEGORY_ALARM}).</li>
+ <li>{@code android.graphics.drawable.Icon} — новый класс, который можно добавить к уведомлениям
+с помощью методов {@code Notification.Builder.setSmallIcon(Icon)} и
+{@code Notification.Builder.setLargeIcon(Icon)}.</li>
+ <li>{@code NotificationManager.getActiveNotifications()} — новый метод, с помощью которого ваше приложение
+может определить, какие из уведомлений в настоящее время активны. Если хотите взглянуть, как может быть реализовано приложение
+с этой функцией, пройдите по ссылке: <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">Пример активных уведомлений</a>.</li>
+</ul>
+
+<h2 id="bluetooth-stylus">Поддержка пера Bluetooth</h2>
+<p>В M Preview улучшена поддержка ввода с помощью пера Bluetooth. Пользователи могут подключить
+совместимое перо Bluetooth к своему смартфону или планшету. Когда перо подключено, данные о его
+положении объединяются со сведениями о степени нажима и нажатия кнопки на пере,
+и таким образом при сенсорном вводе используются не только возможности сенсорного экрана. Ваше приложение может отслеживать
+нажатия кнопки пера и выполнять дополнительные действия, регистрируя в операции новые методы обратного вызова
+{@code View.onStylusButtonPressListener} и
+{@code GestureDetector.OnStylusButtonPressListener}.</p>
+
+<p>Для определения нажатий кнопок пера используйте методы и константы {@link android.view.MotionEvent}:
+</p>
+<ul>
+<li>Если пользователь касается пером кнопки на экране приложения, метод
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} возвращает
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
+<li>В приложениях, разработанных для M Preview, при нажатии пользователем на основную кнопку на пере, метод
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+возвращает{@code MotionEvent.STYLUS_BUTTON_PRIMARY}.
+ Если перо оснащено дополнительной кнопкой, то при нажатии на нее этот метод возвращает
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY}. При нажатии пользователем
+на обе кнопки одновременно, метод возвращает оба значения через оператор «OR»
+({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).</li>
+<li>
+В приложениях, разработанных для более ранних версий платформы, метод
+{@link android.view.MotionEvent#getButtonState() getButtonState()} возвращает
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (при нажатии на основную кнопку на пере),
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (при нажатии дополнительной кнопки на пере) или оба этих значения.
+</li>
+</ul>
+
+<h2 id="ble-scanning">Улучшенное сканирование Bluetooth с низким потреблением энергии</h2>
+<p>
+Если ваше приложение выполняет сканирование Bluetooth с низким потреблением энергии, вы можете при помощи нового метода
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} указать, что обратные вызовы следует уведомлять только в случае, если прежде обнаружен пакет объявления,
+ совпадающий с заданным фильтром
+{@link android.bluetooth.le.ScanFilter}, или если он не обнаруживается в течение заданного периода времени.
+ Такой подход к сканированию обеспечивает еще большую экономию энергии, чем это было возможно в предыдущей
+версии платформы.
+</p>
+
+<h2 id="hotspot">Поддержка Hotspot 2.0, выпуск 1</h2>
+<p>
+В M Preview включена поддержка Hotspot 2.0 (выпуск 1) для устройств Nexus 6 и Nexus 9. Для
+предоставления учетных данных Hotspot 2.0 в вашем приложении используйте новые методы класса
+{@link android.net.wifi.WifiEnterpriseConfig}, такие как {@code setPlmn()} и
+{@code setRealm()}. В объекте {@link android.net.wifi.WifiConfiguration} можно задать поля
+{@link android.net.wifi.WifiConfiguration#FQDN} и {@code providerFriendlyName}.
+Новое свойство{@code ScanResult.PasspointNetwork} показывает, является ли обнаруженная
+сеть точкой доступа Hotspot 2.0.
+</p>
+
+<h2 id="4K-display">Режим отображения в формате 4K</h2>
+<p>Теперь платформа позволяет приложениям запрашивать увеличение разрешения экрана до 4K при обработке изображения
+на совместимом устройстве. Чтобы запросить текущее физическое разрешение, используйте новые API-интерфейсы
+{@code android.view.Display.Mode}. Если элементы пользовательского интерфейса, отрисованные в более низком логическом разрешении, масштабируются до
+более высокого физического разрешения, обратите внимание, что метод физического разрешения
+{@code Display.Mode.getPhysicalWidth()} возвращает результат, который может отличаться от результата выполнения метода логического разрешения
+{@link android.view.Display#getSize(android.graphics.Point) getSize()} .</p>
+
+<p>Можно отправить запрос системе на изменение физического разрешения в активном приложении, задав для окна вашего приложения свойство
+{@code WindowManager.LayoutParams.preferredDisplayModeId}. Эта
+функция особенно полезна в случаях, когда требуется переключиться на разрешение экрана 4K. В режиме отображения в формате 4K элементы
+пользовательского интерфейса отрисовываются в исходном разрешении (например, 1080p) и масштабируются до 4K, однако содержимое
+{@link android.view.SurfaceView} объектов может отображаться с использованием основного разрешения.</p>
+
+<h2 id="behavior-themeable-colorstatelists">Метод ColorStateLists для работы с темами</h2>
+<p>Теперь метод
+{@link android.content.res.ColorStateList} для устройств под управлением M Preview поддерживает атрибуты темы. Методы
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} и
+{@link android.content.res.Resources#getColor(int) getColor()} уже неактуальны. Если вы
+вызываете эти API-интерфейсы, вызовите вместо них новые методы {@code Context.getColorStateList()} или
+{@code Context.getColor()}, Доступные также в библиотеке v4 appcompat
+посредством {@link android.support.v4.content.ContextCompat}.</p>
+
+<h2 id="audio">Работа с аудио</h2>
+
+<p>В M Preview реализован ряд улучшений в области обработки аудиофайлов системой Android, включая следующие: </p>
+<ul>
+ <li>Новые API-интерфейсы {@code android.media.midi}, поддерживающие протокол <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+ для отправки и получения событий
+MIDI.</li>
+ <li>Новые классы: {@code android.media.AudioRecord.Builder} позволяет создавать объекты захвата цифрового аудио, а {@code android.media.AudioTrack.Builder} — объекты воспроизведения,
+а также осуществлять настройку источника
+аудио и свойств приемника, переопределяя исходные системные настройки.</li>
+ <li>Обработчики API-интерфейсов предназначены для связывания аудиофайлов и устройств ввода. Это особенно полезно в случае, если ваше приложение
+предоставляет возможность выполнять голосовой поиск с помощью игрового контроллера или пульта дистанционного управления, подключенного к Android
+TV. Когда пользователь запустит поиск, система вызовет новый метод обратного вызова {@code android.app.Activity.onSearchRequested()}.
+ Чтобы определить, оснащено ли устройство ввода встроенным микрофоном, получите из этого метода обратного вызова объект
+{@link android.view.InputDevice} и вызовите новый метод
+{@code InputDevice.hasMic()}.</li>
+ <li>Новый класс {@code android.media.AudioDevicesManager}, позволяющий пользователю получить список всех
+подключенных источников аудио и приемников. Также можно указать объект
+{@code android.media.OnAudioDeviceConnectionListener}, если требуется, чтобы приложение
+получало уведомления о подключении или отключении аудиоустройств.</li>
+</ul>
+
+<h2 id="video">Работа с видео</h2>
+<p>В M Preview вы обнаружите новые возможности API-интерфейсов для обработки видео, в том числе:</p>
+<ul>
+<li>Новый класс {@code android.media.MediaSync} обеспечивает синхронную обработку потоков
+аудио и видео. Буферы аудио отправляются неблокируемым способом и возвращаются посредством
+обратного вызова. Также имеется поддержка динамической скорости воспроизведения.
+</li>
+<li>Новое событие {@code MediaDrm.EVENT_SESSION_RECLAIMED} указывает на то, что сеанс, запущенный
+приложением, освобожден диспетчером ресурсов. Если в вашем приложении используются сеансы DRM, то это событие
+необходимо обработать и убедиться в том, что освобожденный сеанс не используется.
+</li>
+<li>Новый код ошибки {@code MediaCodec.CodecException.ERROR_RECLAIMED} указывает на то, что
+диспетчер ресурсов освободил ресурс мультимедиа, используемый кодеком. Во всех остальных случаях кодек должен
+быть освобожден, поскольку его необходимо перевести в конечное состояние.
+</li>
+<li>Новый интерфейс {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} позволяет узнать максимальное количество
+ экземпляров кодека, которые могут выполняться одновременно.
+</li>
+<li>Новый {@code MediaPlayer.setPlaybackParams()} метод задает скорость при ускоренном или
+замедленном воспроизведении мультимедиа. Он также позволяет автоматически замедлять или ускорять воспроизведение аудио синхронно с
+видео.</li>
+</ul>
+
+<h2 id="camera">Возможности камеры</h2>
+<p>В M Preview представлены следующие API-интерфейсы для вспышки камеры и повторной обработки
+изображений камерой.</p>
+
+<h3 id="flashlight">API-интерфейс вспышки</h3>
+<p>Если камера оснащена вспышкой, вы можете вызвать метод{@code CameraManager.setTorchMode()},
+чтобы включить или отключить режим фонарика, не запуская камеру. Приложение
+не может заполучить вспышку или камеру в единоличное пользование. Режим фонарика отключается
+и становится недоступен, когда камера недоступна или ресурсов камеры недостаточно для использования вспышки в качестве
+фонарика. Кроме того, другие приложения могут вызывать метод {@code setTorchMode()}
+для отключения режима фонарика. При закрытии приложения, которое включило режим фонарика, этот режим
+отключается.</p>
+
+<p>Чтобы зарегистрировать обратный вызов для уведомления о режиме фонарика, вызовите метод
+{@code CameraManager.registerTorchCallback()}. При первой регистрации обратного вызова
+он сразу же вызывается со сведениями о состоянии режима фонарика для всех известных к настоящему моменту устройств,
+оснащенных вспышкой. При успешном включении или отключении фонарика вызывается метод
+{@code CameraManager.TorchCallback.onTorchModeChanged()}.</p>
+
+<h3 id="reprocessing">API-интерфейс повторной обработки</h3>
+<p>API-интерфейс {@link android.hardware.camera2 Camera2} теперь поддерживает повторную обработку цветовых моделей YUV и изображений в собственном
+формате непрозрачности. Чтобы определить, возможна ли повторная обработка, приложение использует метод
+{@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}. Если устройство поддерживает повторную обработку,
+вы можете создать сеанс захвата изображения с камеры с возможностью повторной обработки, вызвав метод
+{@code CameraDevice.createReprocessableCaptureSession()}, а затем создать запросы на повторную обработку буфера
+входных данных.</p>
+
+<p>Чтобы подключить поток буфера входных данных к модулю повторной обработки изображения с камеры, используйте класс
+{@code ImageWriter}. Чтобы получить пустой буфер, выполните следующие действия:</p>
+
+<ol>
+<li>Вызовите метод {@code ImageWriter.dequeueInputImage()}.</li>
+<li>Заполните буфер входными данными.</li>
+<li>Отправьте буфер в камеру, вызвав метод {@code ImageWriter.queueInputImage()}.</li>
+</ol>
+
+<p>Если вы используете объект {@code ImageWriter} вместе с изображением
+{@code android.graphics.ImageFormat.PRIVATE}, вашему приложению не удастся получить доступ к изображению
+напрямую. Вместо этого передайте изображение {@code ImageFormat.PRIVATE} прямо в
+{@code ImageWriter}, вызвав метод {@code ImageWriter.queueInputImage()} без копии
+буфера.</p>
+
+<p>Класс {@code ImageReader} теперь поддерживает потоки изображений в формате {@code android.graphics.ImageFormat.PRIVATE}.
+ Благодаря этому ваше приложение может организовать циклическую очередь выходных изображений
+{@code ImageReader}, выбрать одно или несколько изображений и отправить их в
+{@code ImageWriter} для повторной обработки камерой.</p>
+
+<h2 id="afw">Возможности Android for Work</h2>
+<p>В M Preview представлены новые API-интерфейсы для Android for Work:</p>
+<ul>
+ <li><strong>Улучшенные элементы управления для корпоративных специализированных устройств.</strong> Владельцу устройства
+теперь доступны новые возможности управления
+корпоративными специализированными устройствами при помощие следующих настроек:
+ <ul>
+ <li>Отключение или повторное включение блокировки клавиатуры с помощью метода
+{@code DevicePolicyManager.setKeyguardEnabledState()}.</li>
+ <li>Отключение или повторное включение строки состояния (включая быстрые настройки, уведомления и
+запуск Google Now путем проведения пальцем по экрану) с помощью метода
+{@code DevicePolicyManager.setStatusBarEnabledState()}.</li>
+ <li>Отключение и повторное включение безопасной загрузки с помощью константы
+{@code DISALLOW_SAFE_BOOT} {@link android.os.UserManager}.</li>
+ <li>Предотвращение отключения экрана, если устройство питается от сети, с помощью константы
+{@code STAY_ON_WHILE_PLUGGED_IN} {@link android.provider.Settings.Global}.</li>
+ </ul>
+ </li>
+ <li><strong>Автоматические установка и удаление приложений владельцами устройств.</strong> Владелец устройства теперь может автоматически
+устанавливать и удалять приложения с помощью API-интерфейсов {@link android.content.pm.PackageInstaller},
+независимо от Google Play for Work. Теперь вы можете подготавливать устройства с помощью компонента «Владелец устройства», который
+получает и устанавливает приложения без участия пользователя. Такая возможность особенно полезна тем, что позволяет подготавливать
+киоски или иные подобные устройства одним касанием, не активируя аккаунт Google.</li>
+<li><strong>Автоматический доступ к корпоративному сертификату.</strong> Теперь, когда приложение вызывает метод
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()},
+владелец профиля или устройства, прежде чем ему будет предложено выбрать сертификат, может вызывать метод
+{@code DeviceAdminReceiver.onChoosePrivateKeyAlias()}, который автоматически предоставит предложению псевдоним.
+ С помощью этой возможности вы можете предоставлять управляемым приложениям доступ к сертификатам без
+вмешательства пользователя.</li>
+<li><strong>Автоматическое принятие обновлений системы.</strong> Настройка параметров обновления системы с помощью
+{@code DevicePolicyManager.setSystemUpdatePolicy()} теперь позволяет компоненту «Владелец устройства» автоматически принять обновление системы
+(например, в киоске) или отложить его на период до 30 дней, причем пользователь
+тоже не сможет установить обновление до истечения этого срока. Более того, администратор может задать ежедневный временной интервал, когда устройство будет принимать
+обновления (например, во те часы, когда киоск не используется). При наличии доступного
+обновления система проверяет, заданы ли параметры обновления системы приложением «Параметры работы»
+, и выполняет соответствующие действия.
+</li>
+<li>
+<strong>Делегированная установка сертификата.</strong> Владелец профиля или устройства теперь может предоставлять
+стороннему приложению возможность вызывать следующие API-интерфейсы управления сертификатом
+{@link android.app.admin.DevicePolicyManager}:
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>Корпоративная настройка защиты от сброса параметров до заводских настроек.</strong> При подготовке компонента «Владелец устройства» теперь
+имеется возможность настроить параметры разблокировки защиты от сброса параметров до заводских настроек (FRP) путем задания пакета
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS}. Приложение NFC Programmer
+может после перезагрузки устройства предоставить эти параметрыс целью разблокировки FRP и его подготовки
+(без необходимости запрашивать ранее настроенную учетную запись Google). Если не изменить эти параметры,
+заводские настройки сохранятся не позволят активировать устройство без ввода активированных ранее
+учетных данных Google.
+<p>Кроме того, задав ограничения на использование служб Google Play, компонент «Владелец устройства» может указать альтернативные учетные записи
+Google для разблокировки FRP и замены учетных записей, активированных на устройстве.</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>Отслеживание использования данных.</strong> Владелец профиля или устройства теперь может запрашивать статистику использования
+данных, которая отображается в разделе <strong>Настройки > Использование данных</strong>, с помощью новых методов
+{@code android.app.usage.NetworkStatsManager}. Владельцам профилей автоматически предоставляется
+разрешение запрашивать данные профиля, которым они управляют, тогда как владельцам устройств предоставляется доступ к сведениям об использовании данных
+основного управляемого пользователя.</li>
+<li><strong>Управление разрешениями на выполнение.</strong>
+<p>Владелец профиля или устройства может задавать политику разрешений
+для всех запросов на использование среды выполнения любых приложений с помощью
+{@code DevicePolicyManager.setPermissionPolicy()}. Это позволяет выбрать, будет ли система предлагать пользователю предоставить разрешение
+как обычно, или она будет автоматически предоставлять разрешения или отказывать в них. В последнем случае
+пользователю не удастся изменить выбор, сделанный владельцем профиля или устройства на экране
+разрешений приложения в разделе <strong>Настройки</strong>.</p></li>
+<li><strong>VPN в разделе «Настройки».</strong> Приложения VPN теперь отображаются в разделе
+<strong>Настройки > Другие сети > VPN</strong>.
+Кроме того, сведения в уведомлениях об использовании VPN теперь зависят от настроек самой VPN.
+ Для владельца профиля уведомления зависят от того, настроена ли VPN для
+управляемого профиля, личного профиля или же того и другого. Для владельца устройства уведомления зависят от того, настроена ли VPN для
+всего устройства.</li>
+<li><strong>Уведомление о состоянии «В работе».</strong> Теперь, когда приложения
+из управляемого профиля выполняет операцию в фоновом режиме, в строке состояния появляется значок портфеля. Кроме того, если после разблокировки устройства
+открывается операция приложения из управляемого профиля, отображается всплывающее уведомление о том,
+что операция выполняется в рабочем профиле.
+</li>
+</ul>
+
+<p class="note">
+ Подробные сведения обо всех изменениях в API-интерфейсах в версии M Developer Preview представлены в <a href="{@docRoot}preview/download.html">отчете о различиях между API-интерфейсами</a>.
+</p>
diff --git a/docs/html-intl/intl/ru/preview/behavior-changes.jd b/docs/html-intl/intl/ru/preview/behavior-changes.jd
new file mode 100644
index 0000000..0623ea7
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=Изменения в работе
+page.keywords=предварительная версия,пакет sdk,совместимость
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Содержание документа</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">Разрешения на выполнение</a></li>
+ <li><a href="#behavior-power">Оптимизация экономии энергии</a>
+ <ol>
+ <li><a href="#behavior-doze">Режим «Doze»</a></li>
+ <li><a href="#behavior-app-standby">Ждущий режим для приложений</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">Подключаемые устройства хранения</a></li>
+ <li><a href="#behavior-apache-http-client">Отказ от HTTP-клиента Apache</a></li>
+ <li><a href="#behavior-audiomanager-Changes">Изменения в классе AudioManager</a></li>
+ <li><a href="#behavior-test-selection">Выделение текста</a></li>
+ <li><a href="#behavior-keystore">Изменения в хранилище ключей Android</a></li>
+ <li><a href="#behavior-network">Изменения в работе с Wi-Fi и сетями</a></li>
+ <li><a href="#behavior-camera">Изменения в службе камеры</a></li>
+ <li><a href="#behavior-art-runtime">Среда выполнения ART</a></li>
+ <li><a href="#behavior-apk-validation">Проверка пакетов APK</a></li>
+ <li><a href="#behavior-afw">Изменения в Android for Work</a></li>
+</ol>
+
+<h2>Различия между API-интерфейсами</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API уровня 22 в M Preview »</a> </li>
+</ol>
+
+
+<h2>См. также:</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">Обзор API-интерфейсов M Developer Preview</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>Наряду с новыми функциями и возможностями, версия M Developer Preview также включает в себя ряд
+системных изменений и изменений в работе API-интерфейсов. В этом документе рассматриваются
+определенные ключевые изменения, о которых следует знать, чтобы учитывать их при разработке приложений.</p>
+
+<p>Если вы ранее публиковали приложения для Android, то примите во внимание,
+что эти изменения в платформе могут повлиять на работу ваших уже опубликованных приложений.</p>
+
+<h2 id="behavior-runtime-permissions">Разрешения на выполнение</h1>
+<p>В M Preview представлена новая модель разрешений: теперь пользователи могут управлять разрешениями приложений
+напрямую во время работы с ними. Такая модель обеспечивает улучшенное управление
+разрешениями и одновременно позволяет оптимизировать установку и автоматическое обновление для разработчиков.
+Пользователи могут предоставлять разрешения или отзывать их отдельно для каждого установленного приложения. </p>
+
+<p>В ваших приложениях, предназначенных для M Preview, следует в обязательном порядке проверить такие разрешения и при необходимости
+запросить их. Чтобы определить, было ли вашему приложению предоставлено разрешение, вызовите новый метод
+{@code Context.checkSelfPermission()}. Чтобы запросить разрешение, вызовите новый метод
+{@code Activity.requestPermission()}. Даже если ваше приложение не предназначено для использования в версии M, вам все равно следует
+протестировать его с использованием новой модели разрешений.</p>
+
+<p>Подробные сведения о поддержке новой модели
+разрешений вашим приложением представлены в статье
+<a href="{@docRoot}preview/features/runtime-permissions.html">Разрешения</a>. Как можно проверить влияние новой модели на ваше приложение, читайте в
+<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">руководстве по тестированию</a></p>
+
+<h2 id="behavior-power">Оптимизация экономии энергии</h2>
+<p>В M Preview реализован ряд новых функций оптимизации экономии энергии для неактивных устройств и приложений.</p>
+
+<h3 id="behavior-doze">Режим «Doze»</h3>
+<p>Если устройство отключено от сети и остается неактивным (и с выключенным экраном) в течение определенного времени,
+оно переходит в режим <em>Doze</em> и старается, чтобы система не выходила из спящего состояния. В этому режиме
+устройство периодически возобновляет свою обычную работу на краткие промежутки времени, чтобы произвести
+синхронизацию и позволить системе выполнить какие-либо отложенные операции.</p>
+
+<p>Когда устройство находится в режиме «Doze», к приложениям применяются следующие ограничения:</p>
+<ul>
+<li>Доступ к сети отключен до тех пор, пока от службы Google Cloud Messaging
+не будет получен высокоприоритетный сигнал побуждения приложения к действию.</li>
+<li>Механизмы <a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">WakeLock</a> игнорируются.</li>
+<li>Будильники, установленные с помощью класса {@link android.app.AlarmManager}, отключаются, кроме
+тех, которые установлены с помощью методов {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}
+и {@code AlarmManager.setAndAllowWhileIdle()}.</li>
+<li>Поиск сетей Wi-Fi не производится.</li>
+<li>Операции синхронизации и заданий для адаптеров синхронизации и {@link android.app.job.JobScheduler} блокируются.
+</li>
+</ul>
+</p>
+<p>После выхода из режима «Doze», устройство приступает к выполнению любых отложенных заданий и операций синхронизации.</p>
+<p>Чтобы протестировать эту функцию, подключите устройство под управлением M Preview к своему компьютеру
+для разработки и выполните следующие команды:
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>Примечание.</strong> В предстоящем выпуске службы
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a>
+реализована возможность назначения сообщений
+с высоким приоритетом. При получении вашим приложением сообщений GCM с высоким приоритетом ему на короткое время предоставляется
+доступ к сети, даже если устройство находится в режиме «Doze».
+</p>
+
+<p>Советы по тестированию работы приложений в режиме «Doze» представлены
+в <a href="{@docRoot}preview/testing/guide.html#doze-standby">руководстве
+по тестированию</a>. </p>
+
+<h3 id="behavior-app-standby">Ждущий режим для приложений</h3>
+<p>В M Preview система может определять, что приложения неактивны, когда они
+не используются. Приложение считается неактивным по прошествии определенного периода времени до тех пор, пока система
+не обнаружит один из следующих сигналов:</p>
+
+<ul>
+<li>приложение явным образом запущено пользователем;</li>
+<li>у приложения имеется процесс, который в настоящее время выполняется на переднем плане (это может быть как сама операция или служба переднего плана,
+так и процесс, используемый другой операцией или службой переднего плана).</li>
+<li>приложение создает уведомление, которое пользователи видят на экране блокировки или в
+области уведомлений.</li>
+<li>пользователь явным образом исключает приложение из списка для оптимизации
+в разделе <strong>Настройки</strong>.</li>
+</ul>
+
+<p>Если устройство отключено от электросети, для приложений, которые считаются неактивными, закрывается доступ к Интернету,
+а их операции синхронизации и задания приостанавливаются. После подключения устройства к электросети доступ к Интернету для приложений возобновится
+и они смогут приступить к выполнению любых ожидающих заданий и операций синхронизации. Если устройство
+неактивно в течение длительного времени, неактивным приложениям раз в день предоставляется доступ к сети.</p>
+
+<p>Чтобы протестировать эту функцию, подключите устройство под управлением M Preview к своему компьютеру
+для разработки и выполните следующие команды:
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>Примечание.</strong> В предстоящем выпуске службы
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud Messaging</a> (GCM)
+реализована возможность назначения сообщений
+с высоким приоритетом. При получении вашим приложением сообщений GCM с высоким приоритетом ему на короткий промежуток времени предоставляется
+доступ к сети, даже если приложение находится в неактивном состоянии.
+</p>
+
+<p>Советы по тестированию работы приложений в ждущем режиме представлены
+в <a href="{@docRoot}preview/testing/guide.html#doze-standby">руководстве
+по тестированию</a>. </p>
+
+<h2 id="behavior-adoptable-storage">Подключаемые устройства хранения</h2>
+<p>
+В M Preview пользователи могут <em>подключать</em> внешние устройства хранения, такие как SD-карты, и использовать их как внутреннее хранилище,
+зашифровав и отформатировав требуемым образом. Благодаря этому
+ пользователи могут переносить как сами приложения, так свои файлы для этих приложений с одного устройства хранения на другое. При переносе
+приложений система руководствуется настройкой
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+в манифесте.</p>
+
+<p>Если ваше приложение работает с указанными ниже API-интерфейсами или полями, следует помнить, что возвращаемые ими пути к файлам
+будут динамически изменяться при перемещении приложения с внутреннего хранилища на внешнее устройство или наоборот.
+При создании путей к файлам настоятельно рекомендуется всегда вызывать эти API-интерфейсы динамическим образом.
+Не используйте жестко запрограммированные пути к файлам и не указывайте созданные ранее полные пути к файлам.</p>
+
+<ul>
+<li>Методы {@link android.content.Context}:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>Поля {@link android.content.pm.ApplicationInfo}:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>Для отладки этой функции в Developer Preview подключите USB-устройство,
+ к устройству Android посредством USB-кабеля On-The-Go (OTG) и выполните следующую команду:</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">Отказ от HTTP-клиента Apache</h2>
+<p>В M Preview удалена поддержка HTTP-клиента Apache. Если ваше приложение, разработанное для
+Android 2.3 (уровень API 9) или более поздней версии, использует этот клиент, вам необходимо воспользоваться вместо него классом {@link java.net.HttpURLConnection}.
+ Этот API-интерфейс более эффективный, поскольку он сокращает использование сетевого трафика за счет прозрачного сжатия
+и кэширования ответов, а также сводит к минимуму потребление энергии. Чтобы продолжить использовать API-интерфейсы HTTP Apache,
+сначала объявите в своем файле {@code build.gradle} следующую зависимость compile-time:
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Вместо OpenSSL в Android теперь будет использоваться библиотека
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+. Если вы используете в ваших приложениях Android NDK, не связывайте его с криптографическими библиотеками,
+которые не входят в состав API-интерфейса NDK, такими как {@code libcrypto.so} и {@code libssl.so}. Эти библиотеки
+не являются общедоступными API-интерфейсами, и в разных выпусках или на разных устройствах они могут быть изменены или разбиты без предварительного уведомления.
+Кроме того, этим вы можете создать уязвимости в системе безопасности вашего продукта. Вместо этого внесите изменения в
+собственный код для вызова криптографических API-интерфейсов Java посредством JNI или статической ссылки на
+библиотеку криптографии по своему выбору.</p>
+
+<h2 id="behavior-audiomanager-Changes">Изменения в классе AudioManager</h2>
+<p>Теперь в платформе не поддерживается настройка уровня громкости напрямую или отключение звука определенных потоков с помощью класса {@link android.media.AudioManager}.
+ Метод {@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} больше не используется. Вместо него следует вызывать метод
+{@code AudioManager.requestAudioFocus()}. Также больше не используется метод
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()};
+вместо него следует вызывать метод {@code AudioManager.adjustStreamVolume()}
+и передавать в него значение направления {@code ADJUST_MUTE} или {@code ADJUST_UNMUTE}.</p>
+
+<h2 id="behavior-test-selection">Выделение текста</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>Теперь, когда пользователь выделяет текст в приложении, такие дополнительные действия как
+<em>Вырезать</em>, <em>Копировать</em> и <em>Вставить</em>, можно отображать на
+<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">перемещаемой панели инструментов</a>. Реализация взаимодействия пользователя с текстом аналогична той, которая используется для
+контекстного меню,
+как описано в статье
+<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">Запуск контекстного меню для отдельных представлений</a>.</p>
+
+<p>Чтобы реализовать перемещаемую панель инструментов для выделения текста, внесите в ваши существующие приложения
+следующие изменения.</p>
+<ol>
+<li>В объекте {@link android.view.View} или {@link android.app.Activity} измените вызовы
+{@link android.view.ActionMode} с
+{@code startActionMode(Callback)} на {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
+<li>Возьмите свою реализацию класса {@code ActionMode.Callback} и сделайте его наследуемой от класса
+{@code ActionMode.Callback2}.</li>
+<li>Переопределите метод {@code Callback2.onGetContentRect()} для указания координат объекта
+{@link android.graphics.Rect} контента (например, прямоугольника выделения текста) в представлении.</li>
+<li>Если расположение прямоугольника больше недействительно и это единственный элемент, который не подлежит пересчитыванию,
+вызовите метод {@code ActionMode.invalidateContentRect()}.</li>
+</ol>
+
+<p>Если вы используете
+<a href="{@docRoot}tools/support-library/index.html">вспомогательную библиотеку Android</a> версии 22.2, то помните, что перемещаемым панелям инструментов
+не свойственна обратная совместимость и по умолчанию для управления объектами {@link android.view.ActionMode}
+используется библиотека appcompat. Это означает, что перемещаемые панели инструментов не будут отображаться. Чтобы включить поддержку
+{@link android.view.ActionMode} в
+{@link android.support.v7.app.AppCompatActivity}, вызовите метод
+{@code android.support.v7.app.AppCompatActivity.getDelegate()}, затем вызовите
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()} для возвращенного объекта
+{@link android.support.v7.app.AppCompatDelegate} и задайте для параметра input
+значение {@code false}. Этот вызов возвращает управление объектами {@link android.view.ActionMode}
+платформе. На устройствах под управлением M Preview платформа поддерживает как режимы
+{@link android.support.v7.app.ActionBar}, так и режимы перемещаемых панелей инструментов, тогда как на устройствах под управлением более ранних версий
+поддерживаются только режимы {@link android.support.v7.app.ActionBar}.</p>
+
+<h2 id="behavior-keystore">Изменения в хранилище ключей Android</h2>
+<p>В M Preview
+<a href="{@docRoot}training/articles/keystore.html">поставщик хранилища ключей Android</a> больше не поддерживает
+DSA. ECDSA по-прежнему поддерживается.</p>
+
+<p>Ключи, для которых не требуется шифрование в хранилище, больше не будут удаляться при отключении или сбросе защищенного экрана блокировки
+(например, пользователем или администратором устройства). Ключи, для которых требуется шифрование
+в хранилище, во время таких событий будут удалены.</p>
+
+<h2 id="behavior-network">Изменения в работе с Wi-Fi и сетями</h2>
+
+<p>Ниже перечислены изменения в API-интерфейсах для работы с Wi-Fi и сетями, реализованные в M Preview.</p>
+<ul>
+<li>Теперь ваши приложения могут изменять состояние объектов {@link android.net.wifi.WifiConfiguration}
+только в том случае, если эти объекты вы создали сами. Вам запрещено изменять или удалять объекты
+{@link android.net.wifi.WifiConfiguration}, созданные пользователем или другими приложениями.
+</li>
+<li>
+Ранее, если приложение принудительно подключало устройство к определенной сети Wi-Fi с помощью метода
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} и настройки
+{@code disableAllOthers=true}, то устройство отключалось от других сетей, например, от
+сотовой сети. В M Preview устройство больше не отключается от других сетей. Если
+в вашем приложении для параметра {@code targetSdkVersion} выбрано значение {@code “20”} или меньше, оно закрепляется за выбранной сетью
+Wi-Fi. Если же параметр {@code targetSdkVersion} имеет значение {@code “21”} или больше, следует использовать
+API-интерфейсы для работы с несколькими сетями (такие как
+{@link android.net.Network#openConnection(java.net.URL) openConnection()},
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} и новый метод
+{@code ConnectivityManager.bindProcessToNetwork()}), чтобы обеспечить отправку
+сетевого трафика приложения в выбранную сеть.</li>
+</ul>
+
+<h2 id="behavior-camera">Изменения в службе камеры</h2>
+<p>В M Preview изменена модель получения доступа к ресурсам в службе камеры.
+ Если раньше запросы доступа обрабатывались в порядке поступления, то теперь процессы с высоким приоритетом имеют преимущество.
+ В работе службы камеры произошли следующие изменения:</p>
+<ul>
+<li>Доступ к ресурсам подсистемы камеры, включая открытие и настройку устройства камеры,
+предоставляется в зависимости от того, какой приоритет имеет процесс клиентского приложения. Процессы приложений с операциями, которые
+видны пользователю или выполняются на переднем плане, обычно имеют более высокий приоритет, что повышает возможность доступа к ресурсам камеры и их
+использования.</li>
+<li>Когда приложение с более высоким приоритетом пытается использовать камеру, активные клиенты камеры для приложений с более низким приоритетом могут быть исключены из очереди доступа.
+ В устаревшем API-интерфейсе {@link android.hardware.Camera}
+это приводит к вызову
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}
+для исключенного клиента. В API-интерфейсе {@link android.hardware.camera2 Camera2} в таких случаях для исключенного клиента вызывается
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}.
+</li>
+<li>На устройствах, где камера позволяет такое, отдельным процессам
+приложения предоставляется возможность одновременно и независимо друг от друга открывать и использовать ресурсы камеры. При этом служба камеры теперь отслеживает и исключает ситуации с использованием ресурсов несколькими процессами,
+когда одновременный доступ вызывает значительное снижение производительности или негативно влияет на возможности
+всех открытых камер. Это изменение
+может привести к отключению доступа для клиентов с более низким приоритетом, даже если к этой же камере не пытаются получить доступ другие приложения.
+
+</li>
+<li>
+Смена пользователя приводит к исключению активных клиентов камеры в приложениях, относящихся к предыдущей учетной записи,
+из очереди доступа. Доступ к камере предоставлен только профилям, которыми владеет активный пользователь устройства.
+Фактически это означает, что если, например, пользователь переключился с гостевой учетной записи на другую, гостевой аккаунт не сможет покинуть запущенные процессы
+, использующие ресурсы подсистемы камеры.
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">Среда выполнения ART</h2>
+<p>Среда выполнения ART теперь должным образом реализует правила доступа для метода
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()}. Это
+изменение позволило устранить проблему, связанную с тем, что в предыдущих версиях система Dalvik неправильно проверяла правила доступа.
+Если ваше приложение использует метод
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} и вы
+хотите переопределить проверки доступа, вызовите метод
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()}, присвоив параметру input
+значение {@code true}. Если ваше приложение использует
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">библиотеку appcompat v7</a> или
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">библиотеку recyclerview v7</a>,
+вам необходимо установить актуальные версии этих библиотек. В противном случае убедитесь в том,
+что любые настраиваемые классы, на которые имеются ссылки из XML, обновлены и их конструкторы классов доступны.</p>
+
+<p>В M Preview обновлено поведение динамического компоновщика. Теперь он распознает разницу между
+{@code soname} библиотеки и путем к ней
+(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">ошибка 6670, о которой сообщалось в открытых источниках</a>),
+и позволяет выполнять поиск по {@code soname}.
+ Приложения, которые ранее работали, но содержали неправильные записи {@code DT_NEEDED}
+(обычно абсолютные пути в файловой системе компьютера для сборки), теперь при загрузке могут выдавать ошибки.</p>
+
+<p>В M Preview правильно реализован флаг {@code dlopen(3) RTLD_LOCAL}. Обратите внимание, что
+{@code RTLD_LOCAL} используется по умолчанию, поэтому будут затронуты вызовы {@code dlopen(3)}, которые явно не используют
+{@code RTLD_LOCAL} (за исключением случаев, когда ваше приложение явным образом использует{@code RTLD_GLOBAL}). Поскольку используется
+{@code RTLD_LOCAL}, символы не будут доступны для библиотек, загруженных с использованием последующих вызовов
+{@code dlopen(3)} (в противоположность ссылкам из записей {@code DT_NEEDED}).</p>
+</p>
+
+<h2 id="behavior-apk-validation">Проверка пакетов APK</h2>
+<p>Теперь платформа более строго подходит к проверке пакетов APK. Пакет APK считается поврежденным, если файл объявлен
+в манифесте, но отсутствует в самом пакете APK. Пакет APK подлежит повторной подписи в случае удаления любого его
+содержимого.</p>
+
+<h2 id="behavior-afw">Изменения в Android for Work</h2>
+<p>В M Preview представлены следующие изменения работы Android for Work:</p>
+<ul>
+<li><strong>Рабочие контакты в контексте личных сведений.</strong> Теперь при просмотре пользователем прошлых звонков в журнале вызовов Google Dialer
+в нем отображаются и рабочие контакты.
+Чтобы скрыть эти сведения в журнале вызовов, установите для параметра {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} значение {@code true}.
+ Рабочие контакты могут отображаться на устройствах через Bluetooth вместе с
+личными контактами только в том случае, если
+для параметра {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} задано значение {@code false}. По
+умолчанию для этого параметра установлено значение {@code true}.
+</li>
+<li><strong>Удаление конфигурации Wi-Fi.</strong> Конфигурации Wi-Fi, добавленные владельцем профиля
+(например, посредством вызова метода
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()}), теперь удаляются при удалении соответствующего рабочего профиля.</li>
+<li><strong>Блокировка конфигурации Wi-Fi.</strong> Пользователю больше не удастся изменить или удалить любые конфигурации Wi-Fi, созданные активным
+владельцем устройства. Пользователь по-прежнему может создавать
+и изменять свои собственные конфигурации Wi-Fi, если для этого пользователя не задана константа
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI} {@link android.os.UserManager}.</li>
+<li><strong>Загрузка приложения «Контроллер политики работы» путем добавления учетной записи Google.</strong> Теперь при добавлении на устройство учетной записи Google,
+для управления которой требуется приложение «Контроллер политики работы»,
+вне управляемого контекста пользователю предлагается установить соответствующее приложение.
+Это также применимо к учетным записям, добавляемым посредством мастера первоначальной настройки устройства в разделе
+<strong>Настройки > Учетные записи</strong>.</li>
+<li><strong>Изменения, касающиеся работы API-интерфейса DevicePolicyManager.</strong>
+Вызов метода {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+затрагивает только использование камеры пользователем, который его вызвал; вызов этого метода из управляемого профиля
+не влияет на работу приложений камеры, выполняющихся для основного пользователя. Кроме того, метод
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+теперь доступен как для владельцев устройства, так и для владельцев профиля. Владелец профиля может задать
+следующие ограничения для блокировки клавиатуры:
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} и
+{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, которые влияют на настройки
+блокировки клавиатуры для родительского пользователя профиля;</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, которое
+влияет только на уведомления, создаваемые приложениями в управляемом профиле.</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/ru/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ru/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..7d12b2d
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=Разрешения
+page.tags=previewresources, androidm
+page.keywords=разрешения, среда выполнения, предварительная версия
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Краткое описание</h2>
+ <ul>
+ <li>Если ваше приложение предназначено для пакета SDK M Preview, пользователю будет предложено предоставить для него разрешения
+ не в процессе установки, а при работе с приложением.</li>
+ <li>Пользователь также может в любой момент отозвать разрешения, воспользовавшись экраном приложения «Настройки»
+.</li>
+ <li>Ваше приложение должно проверять наличие соответствующих разрешений при каждом запуске.
+</li>
+ </ul>
+
+ <h2>Содержание документа</h2>
+ <ol>
+ <li><a href="#overview">Обзор</a></li>
+ <li><a href="#coding">Добавление в код разрешений на выполнение</a></li>
+ <li><a href="#testing">Тестирование разрешений на выполнение</a></li>
+ <li><a href="#best-practices">Советы и рекомендации</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ В версии M Developer Preview представлена новая модель разрешений для приложений, которая
+оптимизирует для пользователей процесс установки и обновления приложений. Если приложение,
+работающее в M Preview, поддерживает новую модель разрешений, пользователю не нужно предоставлять какие-либо
+разрешения при установке приложения или его обновлении. Вместо этого приложение
+запрашивает разрешения, когда в них возникает необходимость, — в таких случаях система отображает для пользователя диалоговое окно с просьбой предоставить
+соответствующее разрешение.
+</p>
+
+<p>
+ Если приложение поддерживает новую модель разрешений, его, тем не менее, можно установить и
+запустить на устройстве под управлением одной из более ранних версий Android, и оно будет использовать старую модель
+разрешений.
+</p>
+
+<h2 id="overview">
+ Обзор
+</h2>
+
+<p>
+ В версии M Developer Preview представлена новая
+модель разрешений. Ниже приводится краткий обзор ее ключевых компонентов:
+</p>
+
+<ul>
+ <li>
+ <strong>Объявление разрешений.</strong> Все разрешения, которые требуются
+приложению, объявляются в его манифесте, как и в более ранних версиях платформы Android.
+ </li>
+
+ <li>
+ <strong>Группы разрешений.</strong> Разрешения
+<em>группируются</em> по типу их функциональных возможностей. Например, в группе разрешений
+<code>CONTACTS</code> находятся разрешения на чтение и запись
+контактов пользователя и информации из его профиля.
+ </li>
+
+ <li>
+ <p><strong>Ограниченные разрешения, предоставляемые во время установки.</strong> Когда
+пользователь устанавливает или обновляет приложение, система предоставляет такому приложению все запрашиваемые им
+разрешения, соответствующие константе {@link
+android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}.
+ Например, разрешения для будильника и подключения к Интернету соответствуют константе {@link
+android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL},
+поэтому они предоставляются автоматически во время установки.
+ </p>
+
+ <p>Система также может предоставить приложению подпись и системные разрешения, как описано в разделе
+<a href="#system-apps">Предоставление приложениям системных разрешений и
+подписи</a>. Пользователю <em>не предлагается</em> предоставить какие-либо разрешения
+во время установки.</p>
+ </li>
+
+ <li>
+ <strong>Предоставление пользователем разрешений во время выполнения.</strong> Когда приложение запрашивает разрешение,
+система отображает для пользователя соответствующее диалоговое окно, а затем вызывает функцию обратного вызова приложения
+с целью уведомить его о том, предоставлены ли необходимые разрешения. Если
+пользователь предоставляет разрешение, приложение получает весь набор разрешений в рамках данной функциональной области
+разрешения, который был объявлен в манифесте приложения.
+ </li>
+
+</ul>
+
+<p>
+ Новая модель разрешений влияет на поведение приложений при работе с функциями, для
+которых требуются разрешения. При использовании этой модели в разработке
+ обратите внимание на следующие рекомендации:
+</p>
+
+<ul>
+
+ <li>
+ <strong>Всегда проверяйте наличие разрешений.</strong> Когда приложению необходимо выполнить
+какое-либо действие, для которого требуется разрешение, оно должно сначала проверить,
+имеется ли у него такое разрешение. Если разрешение отсутствует, приложение
+должно запросить его.
+ </li>
+
+ <li>
+ <strong>Если вам не дают разрешения, выходите из положения красиво.</strong> Если у приложения
+нет нужного разрешения, оно должно обработать эту ошибку разумно.
+ Например, если разрешение требуется лишь для необязательной функции, приложение может
+просто отключить ее. Если же приложение не может работать без данного разрешения,
+ оно может отключить все свои функциональные возможности и проинформировать пользователя,
+что для работы ему требуется разрешение.
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>Рисунок 1.</strong> Экран разрешений в настройках приложения.
+ </p>
+ </div>
+
+ <li>
+ <strong>Разрешения можно отзывать.</strong> Пользователи могут в любое время отозвать разрешения
+приложения. Когда пользователь отзывает разрешения,
+приложение <em>не</em> уведомляется об этом. Снова повторим, что приложение должно всегда проверять наличие
+разрешений, прежде чем выполнять любые действия, для которых они необходимы.
+ </li>
+</ul>
+
+<p class="note">
+ <strong>Примечание.</strong> Если приложение предназначено для M Developer Preview, оно
+<em>должно в обязательном порядке</em> использовать новую модель разрешений.
+</p>
+
+<p>
+ На момент выпуска M Developer Preview не все приложения Google в полной мере реализуют
+ новую модель разрешений. Google обновляет эти приложения
+по мере разработки M Developer Preview, чтобы они должным образом поддерживали настройки
+разрешений.
+</p>
+
+<p class="note">
+ <strong>Примечание.</strong> Если у вашего приложения имеется собственная поверхность API-интерфейса, прежде чем проксировать
+разрешения, убедитесь сначала в том, что у вызывающей операции имеются надлежащие
+разрешения на доступ к данным.
+</p>
+
+<h3 id="system-apps">
+ Предоставление приложениям системных разрешений и подписи
+</h3>
+
+<p>
+ Как правило, когда пользователь устанавливает приложение, система предоставляет такому приложению только те
+разрешения, которые соответствуют константе {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+PROTECTION_NORMAL}. Однако в определенных ситуациях система предоставляет
+приложению больше разрешений:
+</p>
+
+<ul>
+ <li>если приложение является частью системного образа, ему автоматически предоставляются все
+разрешения, обозначенные в его манифесте;
+ </li>
+
+ <li>если в манифесте приложения запрашиваются разрешения, соответствующие константе {@link
+android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE},
+а для подписи приложения использовался то же сертификат, что и для приложения,
+объявившего эти разрешения, система предоставляет запрашивающему приложению необходимые разрешения при
+установке.
+ </li>
+</ul>
+
+<p>
+ В обоих случаях пользователь по-прежнему может в любое время отозвать разрешения, обратившись к
+экрану <strong>Настройки</strong> и выбрав <strong>Приложения
+></strong> <i>название_приложения</i> <strong>> Разрешения</strong>. Поэтому приложение все равноу
+должно проверять наличие разрешений во время выполнения и при необходимости запрашивать их.
+
+</p>
+
+<h3 id="compatibility">
+ Совместимость с предыдущими и последующими версиями
+</h3>
+
+<p>
+ Если приложение не предназначено для M Developer Preview, оно
+продолжает использовать старую модель разрешений даже на устройствах под управлением M Preview. В таком случае при установке приложения
+ система предлагает пользователю предоставить все разрешения,
+указанные в манифесте приложения.
+</p>
+
+<p class="note">
+ <strong>Примечание.</strong> На устройствах под управлением M Developer Preview пользователь может отключить
+разрешения для любого приложения (включая устаревшие приложения) на экране «Настройки».
+ Если пользователь решит отключить разрешения для устаревших приложений, система
+автоматически отключит соответствующие функциональные возможности. Когда приложение пытается
+выполнить операцию, для которой требуется такое разрешение, это
+не обязательно приведет к возникновению исключения. Вместо этого оно может выдать пустой набор данных,
+сигнал об ошибке или иным образом обозначить непредвиденное поведение. Например, если запросить
+календарь, не имея соответствующего разрешения, метод возвратит пустой набор данных.
+</p>
+
+<p>
+ При установке приложения с использованием новой модели разрешений на устройство
+под управлением другой версии ОС, отличной от M Preview,
+система рассматривает такое приложение как любое другое и предлагает
+пользователю предоставить все объявленные разрешения уже во время установки.
+</p>
+
+<p class="note">
+ <strong>Примечание.</strong> В случае с предварительной версией в качестве минимальной версии пакета SDK
+следует задать версию SDK M Preview, чтобы получить возможность компилировать код с помощью пакета SDK предварительной версии. Это означает,
+что вы не сможете протестировать такие приложения на старых платформах
+во время использования предварительной версии для разработчиков.
+</p>
+
+<h3 id="perms-vs-intents">Разрешения и намерения</h3>
+
+<p>
+ Во многих случаях при разработке приложения у вас есть выбор между двумя способами выполнения задачи:
+ вы можете настроить приложение таким образом, чтобы оно самостоятельно запрашивало соответствующие разрешения на выполнение
+операции, или же можно указать ему использовать намерение, чтобы задачу выполнило
+другое приложение.
+</p>
+
+<p>
+ Например, предположим, что вашему приложению требуется возможность делать снимки с помощью камеры устройства.
+ Ваше приложение может запросить разрешение
+<code>android.permission.CAMERA</code>, которое позволит ему напрямую получить доступ
+к камере. Затем ваше приложение использует API-интерфейсы камеры
+для управления камерой и получения снимков. Благодаря такому подходу ваше приложение получает
+полный контроль над процессом фотографирования. Кроме того, это позволяет вам вставить пользовательский интерфейс камеры
+в свое приложение.
+</p>
+
+<p>
+ Если же вам не требуется такой контроль, просто воспользуйтесь намерением {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE}
+для запроса изображения. Когда вы запускаете намерение, пользователю предлагается выбрать
+приложение камеры (если оно отличается от приложения камеры по умолчанию), после чего
+это приложение делает снимок. Приложение камеры возвращает полученное изображение в метод {@link
+android.app.Activity#onActivityResult onActivityResult()} вашего приложения.
+</p>
+
+<p>
+ Аналогичным образом, если вам необходимо позвонить, получить доступ к контактам пользователя и так далее,
+можно создать соответствующее намерение или запросить
+разрешение и напрямую получить доступ к нужным объектам. У каждого подхода есть
+как преимущества, так и недостатки.
+</p>
+
+<p>
+ При использовании разрешений:
+</p>
+
+<ul>
+ <li>Ваше приложение получает полный контроль над взаимодействием пользователя с интерфейсом во время выполнения
+операции. Однако такой широкий контроль усложняет вашу задачу,
+требуя разработать подходящий пользовательский интерфейс.
+ </li>
+
+ <li>Пользователю предлагается предоставить разрешения только один раз, при первом
+выполнении операции. После этого ваше приложение может выполнять операцию без вмешательства
+со стороны пользователя. Однако если пользователь не
+предоставит разрешение (или отзовет его позже), ваше приложение не сможет выполнить
+операцию.
+ </li>
+</ul>
+
+<p>
+ При использовании намерений:
+</p>
+
+<ul>
+ <li>Вам не нужно разрабатывать пользовательский интерфейс для выполнения операции, его предоставляет приложение, которое обрабатывает
+намерение. Однако это также означает, что у вас отсутствует контроль над
+взаимодействием пользователя с интерфейсом. Возможно, пользователю придется взаимодействовать с
+приложением, которое вы даже не видели.
+ </li>
+
+ <li>Если у пользователя нет приложения по умолчанию для выполнения операции, система
+предлагает ему выбрать приложение. Если пользователь не назначит обработчик
+по умолчанию, то при каждом выполнении операции для него может
+отображаться дополнительное диалоговое окно.
+ </li>
+</ul>
+
+<h2 id="coding">Добавление в код разрешений на выполнение</h2>
+
+<p>
+ Если ваше приложение предназначено для новой версии M Developer Preview, вы должны в обязательном порядке использовать
+новую модель разрешений. Это означает, что кроме объявления требуемых разрешений
+в манифесте, вам следует проверять наличие этих разрешений
+во время выполнения, а также запрашивать их, если у вас
+еще нет необходимых разрешений.
+</p>
+
+<h3 id="enabling">
+ Активация новой модели разрешений
+</h3>
+
+<p>
+ Чтобы активировать новую модель разрешений M Developer Preview, задайте для атрибута
+<code>targetSdkVersion</code> приложения значение <code>"MNC"</code>, а для атрибута
+<code>compileSdkVersion</code> – значение <code>"android-MNC"</code>. Это позволит
+включить все функции новой модели разрешений.
+</p>
+
+<p>
+ В случае с предварительной версией необходимо задать для параметра <code>minSdkVersion</code> значение
+<code>"MNC"</code>, чтобы получить возможность компилировать код с помощью пакета SDK предварительной версии.
+</p>
+
+<h3 id="m-only-perm">
+ Назначение разрешений только для M Preview
+</h3>
+
+<p>
+ В манифесте приложения можно использовать новый элемент <code><uses-permission-sdk-m></code>,
+чтобы указать, что разрешение требуется только для M Developer Preview. Если объявить
+разрешение таким способом, то при установке приложения на устройство с более старой версией платформы
+система не будет отправлять запрос пользователю или предоставлять разрешение приложению.
+С помощью элемента <code><uses-permission-sdk-m></code>
+вы можете добавлять новые разрешения
+в обновленные версии вашего приложения без принудительного запроса у пользователей разрешений при
+установке обновления.
+</p>
+
+<p>
+ Если приложение запущено на устройстве под управлением M Developer Preview,
+поведение элемента <code><uses-permission-sdk-m></code> аналогично поведению
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
+ Система не запрашивает у пользователей предоставление каких-либо разрешений, когда они устанавливают
+приложение. Вместо этого приложение само запрашивает разрешения, когда они требуются.
+</p>
+
+<h3 id="prompting">
+ Запрос разрешений
+</h3>
+
+<p>
+ Если ваше приложение использует новую модель разрешений M Developer Preview, то при первом запуске приложения
+на устройстве под управлением
+M Preview пользователю не предлагается предоставить все разрешения. Вместо этого приложение само запрашивает разрешения, когда они
+требуются. Когда приложение запрашивает разрешение, система отображает для пользователя соответствующее диалоговое
+окно.
+</p>
+
+<p>
+ Если ваше приложение запущено на устройстве с пакетом SDK уровня 22 или более низкого, то приложение использует старую
+модель разрешений. То есть при каждой устновке приложения пользователю будет предложено предоставить приложению все разрешения,
+запрашиваемые в манифесте приложения, кроме
+отмеченных элементом <code><uses-permission-sdk-m></code>.
+</p>
+
+<h4 id="check-platform">Проверка платформы, на которой выполняется приложение</h4>
+
+<p>
+ Новая модель разрешений поддерживается только на устройствах под управлением M Developer
+Preview. Прежде чем вызывать любые из этих методов, приложению следует проверить,
+на какой платформе оно выполняется,
+обратившись к значению параметра {@link android.os.Build.VERSION#CODENAME
+Build.VERSION.CODENAME}. Если устройство работает под управлением M Developer Preview,
+то значение параметра{@link android.os.Build.VERSION#CODENAME CODENAME} будет <code>"MNC"</code>.
+</p>
+
+<h4 id="check-for-permission">Проверка наличия у приложения необходимого разрешения</h4>
+
+<p>Когда пользователи пытаются выполнить какое-либо действие, для которого требуется разрешение, приложение
+проверяет, имеется ли у него в настоящее время разрешение на выполнение этой операции. Для этого
+приложение вызывает метод
+<code>Context.checkSelfPermission(<i>permission_name</i>)</code>. Приложению
+следует выполнять такую проверку даже в том случае, если ему известно, что пользователь уже предоставил
+необходимое разрешение,
+поскольку пользователь может в любое время отозвать разрешения приложения. Например, если пользователь
+хочет получить снимок с помощью приложения, то приложение вызывает метод
+<code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>.</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>Таблица 1.</strong> Разрешения и группы разрешений.</p>
+<table>
+ <tr>
+ <th scope="col">Группа разрешений</th>
+ <th scope="col">Разрешения</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">Запрос разрешений при необходимости</h4>
+
+<p>Если у приложения нет требуемого разрешения, оно вызывает метод
+<code>Activity.requestPermissions(String[], int)</code>, чтобы запросить его.
+ Приложение передает в него
+требуемые разрешения, а также целочисленный код запроса.
+ Этот метод выполняется асинхронно: он возвращает результат сразу же, а после того как пользователь
+предоставляет ответ в диалоговом окне, система вызывает метод обратного вызова
+приложения с результатами и передает в него тот же код запроса, который приложение передало в метод
+<code>requestPermissions()</code>.</p>
+
+ <p>Ниже представлен пример кода для проверки наличия у приложения разрешения на чтение контактов
+пользователя и запроса соответствующего разрешения при необходимости.</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">Обработка ответа на запрос разрешений</h4>
+
+<p>
+ Когда приложение запрашивает разрешения, система отображает для пользователя соответствующее диалоговое
+окно. После получения ответа от пользователя система вызывает метод
+<code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+вашего приложения и передает в него ответ пользователя. Вашему приложению необходимо переопределить этот метод. В обратном
+вызове передается тот же код запроса, который вы передали в метод
+<code>requestPermissions()</code>. Например, если приложение запрашивает доступ на
+<code>READ_CONTACTS</code>, то метод обратного вызова
+может быть следующим:
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>Если пользователь предоставляет разрешение, система, в свою очередь, представляет все разрешения,
+запрашиваемые в манифесте приложения для обозначенной функциональной области. Если пользователь
+отказывает в предоставлении разрешения, вам необходимо принять меры. Например, вы можете отключить любые пункты меню
+, для использования которых требуется это разрешение.
+ </li>
+</p>
+
+<p>
+ Когда система предлагает пользователю предоставить разрешение, он может указать системе,
+чтобы она больше не запрашивала это разрешение. В этом случае,
+когда приложение использует метод <code>requestPermissions()</code> для запроса такого разрешения,
+система сразу же отклоняет запрос. При этом система вызывает ваш метод
+<code>onRequestPermissionsResult()</code> так же, как если бы пользователь повторно
+отклонил ваш запрос. Поэтому ваше приложение
+не считает, что имело место прямое взаимодействие с пользователем.
+</p>
+
+<h2 id="testing">Тестирование разрешений на выполнение</h2>
+
+
+<p>
+ Если ваше приложение предназначено для новой версии M Developer Preview, то вы должны протестировать
+его и убедиться в том, что оно должным образом обрабатывает разрешения. Не надо исходить из того, что к началу работы ваше приложение уже имеет
+любые определенные разрешения. При первом запуске приложения оно,
+скорее всего, не будет обладать разрешениями, а в дальнейшем пользователь может в любой момент отозвать или восстановить
+разрешения.
+</p>
+
+<p>
+ Вам следует протестировать ваше приложение и убедиться в том, что оно ведет себя должным образом в
+любых ситуациях, касающихся разрешений. Мы включили в состав пакета SDK M Preview SDK новые команды
+<a href="{@docRoot}tools/help/adb.html">Android
+Debug Bridge (ADB)</a>, чтобы вы могли протестировать ваше приложение с любыми настройками разрешений,
+которые вы хотите попробовать в действии.
+</p>
+
+<h3>
+ Новые команды и параметры ADB
+</h3>
+
+<p>
+ В состав пакета инструментов SDK M Preview входит ряд новых команд, позволяющих протестировать обработку разрешений
+вашим приложением.
+</p>
+
+<h4>
+ Установка с разрешениями
+</h4>
+
+<p>
+ Можно воспользоваться новым параметром <code>-g</code> команды <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a>, который служит для установки
+приложения и предоставления всех разрешений, указанных в его манифесте:
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ Предоставление разрешений и их отзыв
+</h4>
+
+<p>
+ Для предоставления разрешений установленному приложению и их отзыва можно использовать новые команды <a href="{@docRoot}tools/help/adb.html#pm">диспетчера пакетов</a>
+ADB.
+Такая функциональная возможность может быть полезна для автоматизированного тестирования.
+</p>
+
+<p>
+ Для представления разрешения используйте команду <code>grant</code> диспетчера пакетов:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ Например, чтобы представить пакету com.example.myapp разрешение на запись
+аудио, воспользуйтесь следующей командой:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ Чтобы отозвать разрешение, используйте команду <code>revoke</code> диспетчера пакетов:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">Советы и рекомендации</h2>
+
+<p>
+ Новая модель разрешений делает работу пользователей удобнее,
+упрощает для них процесс установки приложений и позволяет лучше понимать,
+что делает то или иное приложение. Чтобы использовать все преимущества
+этой модели, примите во внимание следующие рекомендации:
+</p>
+
+
+<h3 id="bp-what-you-need">Запрашивайте только те разрешения, которые необходимы</h3>
+
+<p>
+ Каждый раз, когда вы запрашиваете разрешение, вы заставляете пользователя делать выбор.
+ Если пользователь отклоняет запрос, соответствующая функциональная возможность приложения отключается.
+ Вам следует сократить количество таких запросов.
+</p>
+
+<p>
+ Например, во многих случаях можно предоставить приложению доступ к нужной функции посредством
+<a href="{@docRoot}guide/components/intents-filters.html">намерения</a> вместо
+запроса разрешений. Если вашему приложению необходимо получить снимки с камеры
+телефона, можно использовать намерение {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+MediaStore.ACTION_IMAGE_CAPTURE}. Когда ваше приложение выполняет намерение, система
+предлагает пользователю выбрать уже установленное приложение камеры для
+получения снимков.
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ Не перегружайте пользователя запросами
+</h3>
+
+<p>
+ Если на пользователя обрушивается сразу много запросов разрешений, он может
+решить, что все это слишком сложно, и просто закрыть приложение. Поэтому разрешения следует
+запрашивать только тогда, когда это необходимо.
+</p>
+
+<p>
+ Иногда приложению жизненно необходимы одно или несколько разрешений.
+В таких случаях имеет смысл запросить все разрешения
+сразу при запуске приложения. Например, если вы разрабатываете приложение для фотографирования, то ему
+однозначно потребуется доступ к камере устройства. Когда пользователь в первый раз запускает приложение,
+он не удивится, если приложение запросит у него разрешение на
+использование камеры. Однако если в этом же приложении имеется функция обмена фотографиями с
+контактами пользователя, возможно, <em>не следует</em> запрашивать соответствующее разрешение при
+первом запуске приложения. Лучше дождаться, когда пользователю потребуется функция обмена контентом,
+и уже тогда запросить разрешение.
+</p>
+
+<p>
+ Если в вашем приложении имеются обучающие материалы, может оказаться целесообразным запросить необходимые разрешения
+после того, как пользователь изучит материалы.
+</p>
+
+<h3 id="bp-explain">
+ Всегда поясняйте, для чего требуются те или иные разрешения
+</h3>
+
+<p>
+ В диалоговом окне запроса разрешений, которое система отображает при вызове вами метода
+<code>requestPermissions()</code>, обозначается требуемое для приложения разрешение,
+однако не указывается, для чего оно необходимо. В некоторых случаях это может озадачить пользователя.
+ Поэтому, прежде чем вызывать метод
+<code>requestPermissions()</code>, стоит пояснить пользователю, для чего вашему приложению требуются разрешения.
+</p>
+
+<p>
+ Например, приложению для фотографирования может потребоваться доступ к службам геолокации, чтобы фотографии можно было снабдить
+геотегами. Не все пользователи знают, что
+фотография может содержать данные о месте съемки, и им может показаться странным, что приложение для фотографирования запрашивает данные
+о местоположении. В этом случае полезно
+рассказать пользователю о такой возможности, <em>прежде</em> чем вызывать метод
+<code>requestPermissions()</code>.
+</p>
+
+<p>
+ Это можно сделать, в частности, внедрив такие запросы в обучающие материалы приложения. В обучающих
+материалах могут содержаться описания каждой из функций приложения с пояснением,
+какие разрешения необходимы для их использования. Например, в обучающий материал по работе с приложением для фотографирования
+можно включить описание функции обмена контентом с контактами, после чего
+пояснить, что для этого пользователю следует предоставить приложению доступ к его контактам.
+ После этого приложение может вызвать метод <code>requestPermissions()</code> для запроса
+доступа. Конечно, не все пользователи обращаются к обучающим материалам,
+поэтому вам по-прежнему следует проверять наличие разрешений и при необходимости запрашивать
+их во время обычной работы приложения.
+</p>
diff --git a/docs/html-intl/intl/ru/preview/overview.jd b/docs/html-intl/intl/ru/preview/overview.jd
new file mode 100644
index 0000000..6ed1d20
--- /dev/null
+++ b/docs/html-intl/intl/ru/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=Обзор программы
+page.metaDescription=Добро пожаловать в программу Android M Developer Preview, участники которой получают всё необходимое для тестирования и оптимизации своих приложений для следующей версии платформы Android.
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ Добро пожаловать в программу <strong>Android M Developer Preview</strong>, участники которой получают всё необходимоедля тестирования и оптимизации своих приложений для следующей версии платформы Android.
+
+ Это бесплатная программа, и приступить к ее использованию можно прямо сейчас, загрузив
+инструменты M Developer Preview.
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ Системные образы эмулятора и оборудования
+ </h5>
+
+ <p>
+ Запускайте и тестируйте ваши приложения на устройствах Nexus 5, 6, 9 и Player (для Android TV), а также в эмуляторе.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Самый актуальный код платформы
+ </h5>
+
+ <p>
+ Во время знакомства с предварительной версией платформы мы будем предоставлять различные обновления, поэтому вы сможете протестировать самые актуальные изменения в платформе.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Получение обновлений по беспроводной связи
+ </h5>
+
+ <p>
+ После прошивки своего устройства для работы с предварительной версией платформы вы сможете получать обновления по беспроводной связи.
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ Новые возможности и новые функции
+ </h5>
+
+ <p>
+ Начните уже заранее реализовывать в своих приложениях поддержку расширенной функциональности платформы, например, новую модель разрешений на выполнение и функции сбережения энергии.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Приоритетная обработка отчетов об ошибках от разработчиков
+ </h5>
+
+ <p>
+ В течение первых нескольких недель мы будем рассматривать отчеты об ошибках, поступающие от разработчиков, в приоритетном порядке, поэтому не теряйте времени и приступайте к тестированию и составлению отзывов как можно раньше.
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ Отзывы и поддержка
+ </h5>
+
+ <p>
+ Отправляйте нам отчеты об ошибках и предоставляйте свои отзывы с помощью нашей <a href="https://code.google.com/p/android-developer-preview/">системы отслеживания проблем</a>.
+ Обменивайтесь идеями и предложениями с другими разработчиками в <a href="http://g.co/dev/AndroidMDevPreview">сообществе разработчиков Android M</a>.
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ График и обновления
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ Тестирование версии M Developer Preview запланировано на период с 28 мая до выпуска окончательной версии пакета SDK Android M, который
+состоится незадолго до публикации новой платформы в открытом доступе в
+третьем квартале 2015 г.
+</p>
+
+<p>
+ На ключевых этапах разработки платформы мы предоставим обновления для тестовых устройств.
+ Ниже перечислены предварительные даты этих ключевых этапов.
+</p>
+
+<ul>
+ <li>
+ <strong>Preview 1</strong> (первоначальный выпуск версии Preview, конец мая)
+ </li>
+
+ <li>
+ <strong>Preview 2</strong> (конец июня/начало июля)
+ </li>
+
+ <li>
+ <strong>Preview 3</strong> (почти окончательный выпуск, конец июля)
+ </li>
+</ul>
+
+<p>
+ Завершающим этапом обновлений станет выход <strong>окончательной версии пакета SDK</strong> (в третьем квартале),
+где будут представлены официальные API-интерфейсы для новой версии Android, а также
+окончательные версии функций и поведений системы.
+</p>
+
+<p>
+ Мы настоятельно рекомендуем вам в ходе тестирования и разработки приложений для Android M <strong>постоянно
+обновлять вашу среду разработки</strong> по мере выхода обновлений для версии Preview.
+ Чтобы упростить этот процесс, мы будем отправлять на устройства, которые уже прошиты для работы с предварительной версией платформы, <strong>обновления по беспроводной сети</strong>.
+Мы также будем предоставлять вам системные образы, которые можно
+загрузить и использовать для прошивки устройства вручную.
+</p>
+<p class="note">
+ <strong>Примечание.</strong> Окончательные версии пакета SDK и системных образов не будут отправляться по беспроводной сети,
+их придется <strong>вручную установить</strong> на
+тестовые устройства.</strong>
+</p>
+
+<p>
+ Мы будем сообщать о появлении обновлений для версии Preview в <a href="http://android-developers.blogspot.com/">блоге разработчиков Android</a>, а
+также на этом сайте и в
+<a href="http://g.co/dev/AndroidMDevPreview">сообществе разработчиков Android M</a>.
+</p>
+
+<h2 id="preview_tools">
+ Что входит в состав Preview?
+</h2>
+
+<p>
+ M Developer Preview содержит всё, что вам необходимо для тестирования ваших существующих приложений на экранах различных размеров,
+тестирования с использованием различных сетевых технологий, чипсетов ЦП и графических процессоров,
+ а также на различных архитектурах оборудования.
+</p>
+
+<h4>
+ Инструменты SDK
+</h4>
+
+<p>
+ С помощью менеджера SDK в <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> вы можете загрузить следующие компоненты:
+</p>
+
+<ul>
+ <li><strong>Инструменты SDK</strong> для M Developer Preview.
+ </li>
+
+ <li><strong>Системный образ эмулятора</strong> (32- и
+64-разрядная версии) для M Developer Preview.
+ </li>
+
+ <li><strong>Системный образ эмулятора для Android TV</strong> (32- и
+32-разрядная версии)
+ </li>
+</ul>
+
+<h4>
+ Системные образы оборудования
+</h4>
+
+<p>
+ На странице
+<a href="download.html">Загрузки</a> можно скачать следующие системные образы оборудования:
+</p>
+
+<ul>
+ <li>
+ Системный образ устройства <strong>Nexus 5</strong> (GSM/LTE) («hammerhead»)
+ </li>
+
+ <li>
+ Системный образ устройства <strong>Nexus 6</strong> («shamu»)
+ </li>
+
+ <li>
+ Системный образ устройства <strong>Nexus 9</strong> (Wi-Fi) («volantis»)
+ </li>
+
+ <li>
+ Системный образ устройства <strong>Nexus Player</strong> (Android TV) («fugu»)
+ </li>
+</ul>
+
+<h4>
+ Документация и примеры кода
+</h4>
+
+<p>
+ Здесь вы можете найти документацию, где представлены подробные сведения о версии Preview:
+</p>
+
+<ul>
+ <li>
+ Документ, посвященный <a href="setup-sdk.html">настройке пакета SDK</a>, с пошаговыми инструкциями
+по началу работы.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">Руководство по тестированию</a> и <a href="behavior-changes.html">обзор изменений в работе</a> с указанием ключевых областей для тестирования.
+ </li>
+
+ <li>Документация по новым API-интерфейсам, включая <a href="api-overview.html">обзор API-интерфейсов</a>,
+<a href="{@docRoot}preview/download.html#docs">справочник по API-интерфейсам</a> для загрузки и подробные руководства для разработчиков,
+в которых освещаются такие ключевые функции платформы,
+как <a href="{@docRoot}preview/features/runtime-permissions.html">разрешения</a>,
+<a href="{@docRoot}preview/backup/index.html">резервное копирование приложений</a> и многое другое.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">Примеры кода</a>, где можно посмотреть реализацию поддержки
+разрешений и других новых функций.
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/support.html#release-notes">Примечания к выпуску</a> для текущей версии
+M Developer Preview, включая информацию об изменениях и различные отчеты.
+ </li>
+</ul>
+
+<h4>
+ Ресурсы поддержки
+</h4>
+
+<p>
+ При тестировании и разработке приложений для M
+Developer Preview рекомендуем пользоваться следующими ресурсами поддержки:
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">Система отслеживания проблем M
+Developer Preview</a> — это ваш <strong>основной канал для предоставления своих
+отзывов.</strong> С ее помощью вы можете сообщать нам об обнаруженных ошибках, проблемах производительности, а также предоставлять общие отзывы.
+ Также можно ознакомиться с <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">известными проблемами</a>
+и действиями по их устранению.
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Сообщество разработчиков Android
+M</a> — это сообщество Google+, где можно <strong>общаться с другими
+разработчиками</strong>, работающими с Android M. Делитесь в сообществе своими наблюдениями
+и идеями, а также находите ответы на вопросы об Android M.
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ Выбор целевого уровня, предварительные версии API-интерфейсов и публикация приложений
+</h2>
+
+<p>
+ Выпуск Android M Developer Preview предназначен исключительно для разработки и
+<strong>не имеет стандартного уровня API</strong>. Если вы не хотите
+проверять свое приложение на совместимость (хотя мы настоятельно рекомендуем делать это),
+выберите целевой уровень M Developer Preview, задав для параметра <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+своего приложения значение <code>“MNC”</code>.
+</p>
+
+<p>
+ В Android M Developer Preview представлены <strong>предварительные версии API-интерфейсов</strong>
+—. Такие API-интерфейсы не будут официально опубликованы до выпуска окончательной версии пакета SDK,
+ намеченого на третий квартал 2015 г. Это означает, что в будущем можно
+<strong>ожидать незначительных изменений в API-интерфейсах</strong>, особенно в
+первые недели действия программы. Каждое обновление
+Android M Developer Preview будет включать обзор изменений.
+</p>
+
+<p class="note">
+ Обратите внимание, что несмотря на возможные изменения в предварительных версиях API-интерфейсов, соответствующие расширения функциональности системы,
+такие как разрешения на выполнение и функции сбережения энергии, работают стабильно и уже готовы для
+тестирования.
+</p>
+
+<p>
+ Что касается публикации приложений, то политика Google Play <strong>однозначно запрещает публикацию приложений,
+разработанных для M Developer Preview</strong>. После выхода окончательной версии пакета SDK Android M
+вы сможете выбрать официальный целевой уровень API Android M и приступить
+к публикации ваших приложений в магазине Google Play. Тем временем, если вы хотите распространить приложение, предназначенное для
+тестировщиков Android M, то используйте для этого электронную почту или разместите такие приложения на своем сайте
+для прямой загрузки.
+</p>
+
+<h2 id="get_started">
+ Начало работы
+</h2>
+
+<p>
+ Чтобы приступить к тестированию своего приложения, выполните указанные ниже действия.
+</p>
+
+<ol>
+ <li>Ознакомьтесь с <a href="{@docRoot}preview/api-overview.html">обзором API-интерфейсов</a>
+и сведениями об <a href="{@docRoot}preview/behavior-changes.html">изменениях в работе</a>, чтобы получить
+представление о новых возможностях платформы и о том, как это может повлиять на ваши приложения. В частности, узнайте подробнее о новой модели
+<a href="{@docRoot}preview/features/runtime-permissions.html">разрешений на
+выполнение</a>, функциях сбережения энергии и автоматическом резервном копировании.
+ </li>
+
+ <li>Настройте свою среду, руководствуясь инструкциями по
+<a href="{@docRoot}preview/setup-sdk.html">настройке пакета SDK Preview</a>
+и конфигурированию тестовых устройств.
+ </li>
+
+ <li>Выполните
+<a href="https://developers.google.com/android/nexus/images">инструкции по прошивке</a>, чтобы прошить устройства
+Nexus 5, 6, 9 и Player с использованием последнего системного образа M Developer Preview. После прошивки вашего устройства для разработки
+обновления Preview на него будут приходить по беспроводной сети.</a>
+ </li>
+
+ <li>Загрузите <a href="{@docRoot}preview/download.html#docs">справочник по API-интерфейсам M Preview</a>
+и <a href="{@docRoot}preview/samples.html">примеры кода M Preview</a>
+, чтобы узнать больше о новых возможностях API-интерфейсов и о том, как использовать их в ваших
+приложениях.
+ </li>
+
+ <li>Присоединяйтесь к <a href="http://g.co/dev/AndroidMDevPreview">сообществу разработчиков Android
+M</a>, чтобы всегда быть в курсе последних новостей и общаться с другими
+разработчиками, работающими с новой платформой.
+ </li>
+</ol>
+
+<p>
+ Благодарим за участие в программе Android M Developer!
+</p>
diff --git a/docs/html-intl/intl/zh-cn/preview/api-overview.jd b/docs/html-intl/intl/zh-cn/preview/api-overview.jd
new file mode 100644
index 0000000..c64a38e
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=API 概览
+page.keywords=预览版,sdk,兼容性
+page.tags=previewresources, androidm
+sdk.platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本文内容
+<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">显示详细信息</span>
+ <span class="less" style="display:none">显示精简信息</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">应用链接</a></li>
+ <li><a href="#backup">自动备份应用</a></li>
+ <li><a href="#authentication">身份验证</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">指纹身份验证</a></li>
+ <li><a href="#confirm-credential">确认凭据</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">直接共享</a></li>
+ <li><a href="#voice-interactions">语音交互</a></li>
+ <li><a href="#assist">助手 API</a></li>
+ <li><a href="#notifications">通知</a></li>
+ <li><a href="#bluetooth-stylus">蓝牙触控笔支持</a></li>
+ <li><a href="#ble-scanning">改进的蓝牙低功耗扫描</a></li>
+ <li><a href="#hotspot">Hotspot 2.0 第 1 版支持</a></li>
+ <li><a href="#4K-display">4K 显示模式</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">主题化 ColorStateList</a></li>
+ <li><a href="#audio">音频功能</a></li>
+ <li><a href="#video">视频功能</a></li>
+ <li><a href="#camera">相机功能</a>
+ <ol>
+ <li><a href="#flashlight">闪光灯 API</a></li>
+ <li><a href="#reprocessing">相机再处理</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Android for Work 功能</a></li>
+</ol>
+
+<h2>API 差异</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API 级别 22 至 M 预览版»</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M 开发者预览版可让您预览即将推出的 Android 平台版本为用户和应用开发者提供的新功能。
+
+本文旨在介绍其中最值得关注的 API。</p>
+
+<p>M 开发者预览版的适用对象是<strong>喜欢尝鲜的开发者</strong>和<strong>测试人员</strong>。
+如果您有兴趣影响 Android 框架的发展方向,<a href="{@docRoot}preview/setup-sdk.html">欢迎试用 M 开发者预览版</a>并向我们提供反馈!
+
+
+</p>
+
+<p class="caution"><strong>注意</strong>:请不要在 Google Play 商店中发布基于 M 开发者预览版的应用。
+</p>
+
+<p class="note"><strong>注:</strong>本文经常提及的一些类和方法在 <a href="{@docRoot}">developer.android.com</a> 上尚未提供相关参考资料。
+这些 API 元素在本文中设置为 {@code code style} 格式(不带超链接)。
+如需查看这些元素的初步 API 文档,请下载<a href="{@docRoot}preview/download.html#docs">预览版参考资料</a>。
+</p>
+
+<h3>重要的行为变更</h3>
+
+<p>如果您之前发布过 Android 应用,请注意您的应用可能受到平台变化的影响。
+</p>
+
+<p>如需了解完整信息,请参阅<a href="behavior-changes.html">行为变更</a>。</p>
+
+<h2 id="app-linking">应用链接</h2>
+<p>此预览版通过提供功能更强大的应用链接,增强了 Android 的意向系统。您可以利用此功能将应用与您拥有的某个 Web 域关联。
+平台可以根据此关联确定在处理特定 Web 链接时默认使用的应用,跳过提示用户选择应用的步骤。如需了解如何实现此功能,请参阅<a href="{@docRoot}preview/features/app-linking.html">应用链接</a>。
+
+
+
+
+<h2 id="backup">自动备份应用</h2>
+<p>现在,系统可以自动为应用执行完整数据备份和恢复。对于以 M 预览版为目标平台的应用,系统会默认启用此行为,您无需额外添加任何代码。
+如果用户删除其 Google 帐户,其备份数据也会被删除。
+如需了解该功能的工作方式以及配置文件系统备份内容的方法,请参阅<a href="{@docRoot}preview/backup/index.html">自动备份应用</a>。
+
+</p>
+
+<h2 id="authentication">身份验证</h2>
+<p>本预览版提供一些新的 API,在受支持的设备上,用户只需扫描其指纹即可完成身份验证,还可检查系统最后一次使用设备解锁机制(如锁屏密码)对用户进行身份验证是发生在多久之前。
+
+这些 API 可与 <a href="{@docRoot}training/articles/keystore.html">Android 密钥库系统</a>结合使用。
+</p>
+
+<h3 id="fingerprint-authentication">指纹身份验证</h3>
+
+<p>如需通过指纹扫描验证用户身份,请获取新增
+{@code android.hardware.fingerprint.FingerprintManager} 类的实例,并调用
+{@code FingerprintManager.authenticate()} 方法。您的应用必须运行在带有指纹传感器的兼容设备上。
+您必须在应用中实现指纹身份验证流的用户界面,并在 UI 中使用标准 Android 指纹图标。<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">示例应用</a>中包含有 Android 指纹图标 ({@code c_fp_40px.png})。请注意,如果您要开发多个使用指纹身份验证的应用,每个应用必须独立验证用户的指纹。
+
+
+
+
+</p>
+
+<p>如需在您的应用中使用此功能,请先在清单文件中添加 {@code USE_FINGERPRINT} 权限。
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>如需查看指纹身份验证的应用实现,请参阅<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">指纹对话框示例</a>。
+
+</p>
+
+<p>如果您要测试此功能,请执行以下步骤:</p>
+<ol>
+<li>如果您尚未安装 Android SDK 工具 24.3 修订版,请执行此操作。</li>
+<li>转到<strong>设置 > 安全 > 指纹</strong>,然后按照登记说明在模拟器中登记新指纹。
+</li>
+<li>使用模拟器通过以下命令模拟指纹触摸事件。
+使用同一命令模拟锁屏上或应用中的指纹触摸事件。
+
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>在 Windows 上,您可能需要运行带有
+{@code finger touch <finger_id>} 参数的 {@code telnet 127.0.0.1 <emulator-id>} 命令。
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">确认凭据</h3>
+<p>您的应用可以根据用户在多久之前最后一次解锁设备来验证其身份。此功能让用户不必费心记忆应用特定密码,您也无需实现自己的身份验证用户界面。
+
+您的应用应当利用此功能并结合实现公钥或私钥,以进行用户身份验证。
+</p>
+
+<p>如需设置成功验证用户身份后可再次使用同一密钥的超时持续时间,请在设置 {@link javax.crypto.KeyGenerator} 或
+{@link java.security.KeyPairGenerator} 时调用新增的
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+ 方法。
+此功能目前适用于对称加密操作。
+</p>
+
+<p>避免过多显示重新验证对话框 -- 您的应用应尝试先使用加密对象,如果超时到期,请使用
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} 方法在您的应用内重新验证用户身份。
+
+
+</p>
+
+<p>如需查看此功能的应用实现,请参阅<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">确认凭据示例</a>。
+
+</p>
+
+<h2 id="direct-share">直接共享</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>本预览版为您提供的 API 可让用户直观、快捷地进行共享。现在,您可以定义可在您的应用内启动特定活动的<em>直接共享目标</em>。这些直接共享目标通过“共享”<em></em>菜单公开给用户。
+
+此功能让用户可以向其他应用内的目标(如联系人)共享内容。
+例如,直接共享目标可以启动另一社交网络应用中的某个活动,让用户可以直接向该应用中的某位朋友或某个社区共享内容。
+
+</p>
+
+<p>如需启用直接共享目标,您必须定义一个类,用于扩展
+{@code android.service.} <br>
+{@code chooser.ChooserTargetService} 类。在清单文件中声明您的
+{@code ChooserTargetService}。在该声明内,指定
+{@code BIND_CHOOSER_TARGET_SERVICE} 权限和一个带有
+{@code SERVICE_INTERFACE} 操作的意向过滤器。</p>
+<p>以下示例展示了如何在清单文件中声明 {@code ChooserTargetService}。
+</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>对于您想要向 {@code ChooserTargetService} 公开的每个活动,请在您的应用清单文件中为其添加一个名为
+{@code "android.service.chooser.chooser_target_service"} 的
+{@code <meta-data>} 元素。
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">语音交互</h2>
+<p>
+本预览版提供了一个新的语音交互 API,与
+<a href="https://developers.google.com/voice-actions/" class="external-link">语音操作</a>一起使用时,可让您为应用内建对话式语音体验。
+调用
+{@code android.app.Activity.isVoiceInteraction()} 方法可确定您的活动是否为响应语音操作而启动。
+如果是这样,则您的应用可以使用
+{@code android.app.VoiceInteractor} 类请求用户进行语音确认、从选项列表中进行选择以及执行其他操作。
+如需了解有关实现语音操作的更多信息,请参阅
+<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">语音操作开发者网站</a>。
+</p>
+
+<h2 id="assist">助手 API</h2>
+<p>
+本预览版提供了一种让用户通过助手程序与应用进行互动的新方式。如需使用此功能,用户必须启用助手以使用当前上下文。
+启用后,用户可通过长按<strong>主页</strong>按钮在任何应用内召唤助手。
+</p>
+<p>您的应用可通过设置
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE} 标志选择不与助手共享当前上下文。除了平台传递给助手的一组标准信息外,您的应用还可利用新增的 {@code android.app.Activity.AssistContent} 类共享其他信息。
+
+</p>
+
+<p>如需为助手提供您的应用内的其他上下文,请执行以下步骤:</p>
+
+<ol>
+<li>实现 {@link android.app.Application.OnProvideAssistDataListener} 接口。</li>
+<li>利用
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()} 注册此侦听器。</li>
+<li>如需提供特定于活动的上下文信息,请替代
+{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+ 回调和新增的 {@code Activity.onProvideAssistContent()} 回调(可选操作)。
+</ol>
+
+<h2 id="notifications">通知</h2>
+<p>本预览版针对通知功能引入了下列 API 变更:</p>
+<ul>
+ <li>新增了 {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} 过滤级别,它对应于新增的“仅闹铃”<em></em>免打扰模式。
+</li>
+ <li>新增了 {@code Notification.CATEGORY_REMINDER} 类别值,用于区分用户安排的提醒与其他事件 ({@link android.app.Notification#CATEGORY_EVENT}) 和闹铃 ({@link android.app.Notification#CATEGORY_ALARM})。
+
+
+</li>
+ <li>新增了 {@code android.graphics.drawable.Icon} 类,可通过 {@code Notification.Builder.setSmallIcon(Icon)} 方法和
+{@code Notification.Builder.setLargeIcon(Icon)} 方法附加到通知上。
+</li>
+ <li>新增了 {@code NotificationManager.getActiveNotifications()} 方法,让您的应用能够了解哪些通知目前处于活动状态。
+如需查看使用此功能的应用实现,请参阅<a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">活动通知示例</a>。
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">蓝牙触控笔支持</h2>
+<p>本预览版改善了对用户使用蓝牙触控笔进行输入的支持。用户可将兼容的蓝牙触控笔与其手机或平板电脑配对并建立连接。
+连接后,来自触摸屏的位置信息将与来自触控笔的压力和按键信息融合,从而实现比单纯使用触摸屏更丰富的表达。
+
+您的应用可以通过在活动中注册新增的
+{@code View.onStylusButtonPressListener} 回调和 {@code GestureDetector.OnStylusButtonPressListener}
+ 回调侦听触控笔按键动作并执行辅助操作。
+</p>
+
+<p>可使用 {@link android.view.MotionEvent} 方法和常量来检测触控笔按键交互:
+</p>
+<ul>
+<li>如果用户使用带按键的触控笔触按应用屏幕,
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} 方法会返回
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}。</li>
+<li>对于以 M 预览版为目标平台的应用,当用户按触控笔的主按键时,
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+ 方法会返回 {@code MotionEvent.STYLUS_BUTTON_PRIMARY}。
+如果触控笔有辅助按键,当用户按下它时,同一方法会返回
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY}。如果用户同时按下两个按键,该方法会同时返回通过 OR 运算符连接起来的两个值 ({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY})。
+
+</li>
+<li>
+对于以较低平台版本为目标的应用,
+{@link android.view.MotionEvent#getButtonState() getButtonState()} 方法返回
+{@link android.view.MotionEvent#BUTTON_SECONDARY}(按下触控笔主按键时)、
+{@link android.view.MotionEvent#BUTTON_TERTIARY}(按下触控笔辅助按键时)之一或同时返回这两者。
+</li>
+</ul>
+
+<h2 id="ble-scanning">改进的蓝牙低功耗扫描</h2>
+<p>
+如果您的应用执行蓝牙低功耗扫描,可以使用新增的
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} 方法指定您只希望在下列条件下通知回调:首次找到与设置的
+{@link android.bluetooth.le.ScanFilter} 匹配的播发数据包并且该数据包已有一段时间没有出现。
+
+这种扫描方法与旧平台版本中提供的方法相比更加节能。
+
+</p>
+
+<h2 id="hotspot">Hotspot 2.0 第 1 版支持</h2>
+<p>
+本预览版在 Nexus 6 和 Nexus 9 设备上添加了对 Hotspot 2.0 第 1 版规范的支持。如需在您的应用中设置 Hotspot 2.0 凭据,请使用新增的
+{@link android.net.wifi.WifiEnterpriseConfig} 类方法,如 {@code setPlmn()} 方法和
+{@code setRealm()} 方法。
+在 {@link android.net.wifi.WifiConfiguration} 对象中,您可以设置
+{@link android.net.wifi.WifiConfiguration#FQDN} 字段和 {@code providerFriendlyName} 字段。
+新增的 {@code ScanResult.PasspointNetwork} 属性可指示检测到的网络是否为 Hotspot 2.0 接入点。
+
+</p>
+
+<h2 id="4K-display">4K 显示模式</h2>
+<p>现在,平台允许应用在兼容硬件上请求将显示分辨率升级到 4K 渲染。
+如需查询当前物理分辨率,请使用新增的
+{@code android.view.Display.Mode} API。请注意,如果 UI 是以较低逻辑分辨率绘制并通过放大达到更高的物理分辨率,则
+{@code Display.Mode.getPhysicalWidth()} 方法返回的物理分辨率可能不同于 {@link android.view.Display#getSize(android.graphics.Point) getSize()} 所报告的逻辑分辨率。
+
+</p>
+
+<p>您可以通过设置应用窗口的 {@code WindowManager.LayoutParams.preferredDisplayModeId} 属性请求系统更改应用运行时的物理分辨率。
+如果您想切换到 4K 显示分辨率,此功能会很有帮助。
+在 4K 显示模式下,UI 仍然以原始分辨率(如 1080p)渲染,通过放大达到 4K,但
+{@link android.view.SurfaceView} 对象可能会以原生分辨率显示内容。
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">主题化 ColorStateList</h2>
+<p>对于运行 M 预览版的设备,现在支持在
+{@link android.content.res.ColorStateList} 中使用主题属性。
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} 方法和
+{@link android.content.res.Resources#getColor(int) getColor()} 方法已弃用。如果您要调用这些 API,请改为调用新增的 {@code Context.getColorStateList()} 方法或
+{@code Context.getColor()} 方法。
+还可在 v4 appcompat 库中通过 {@link android.support.v4.content.ContextCompat} 使用这些方法。
+</p>
+
+<h2 id="audio">音频功能</h2>
+
+<p>本预览版增强了 Android 上的音频处理功能,包括: </p>
+<ul>
+ <li>通过新增的 {@code android.media.midi} API 提供了对 <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
+ 协议的支持。使用这些 API 可发送和接收 MIDI 事件。
+</li>
+ <li>新增了 {@code android.media.AudioRecord.Builder} 类和 {@code android.media.AudioTrack.Builder}
+ 类,分别用于创建数字音频采集和回放对象,还可用于配置音频源和接收器属性来替代系统默认值。
+</li>
+ <li>用于关联音频和输入设备的 API 钩子。如果您的应用允许用户通过与 Android TV 相连的游戏控制器或遥控器启动语音搜索,此功能尤为有用。系统会在用户启动搜索时调用新增的 {@code android.app.Activity.onSearchRequested()} 回调。
+
+
+如需确定用户的输入设备是否内置麦克风,请从该回调检索 {@link android.view.InputDevice} 对象,然后调用新增的
+{@code InputDevice.hasMic()} 方法。
+</li>
+ <li>新增了 {@code android.media.AudioDevicesManager} 类,让您可以检索连接的所有源设备和接收器音频设备列表。
+如果您想让应用在音频设备连接或断开时收到通知,还可以指定一个
+{@code android.media.OnAudioDeviceConnectionListener} 对象。
+</li>
+</ul>
+
+<h2 id="video">视频功能</h2>
+<p>本预览版为视频处理 API 添加了新功能,包括:</p>
+<ul>
+<li>新增了 {@code android.media.MediaSync} 类,可帮助应用同步渲染音频流和视频流。
+音频缓冲区以非锁定方式提交,并通过回调返回。
+此外,它还支持动态回放速率。
+</li>
+<li>新增了 {@code MediaDrm.EVENT_SESSION_RECLAIMED} 事件,它表示应用打开的会话已被资源管理器收回。
+如果您的应用使用 DRM 会话,则应处理此事件,并确保不使用收回的会话。
+
+</li>
+<li>新增了 {@code MediaCodec.CodecException.ERROR_RECLAIMED} 错误代码,它表示资源管理器收回了编解码器使用的媒体资源。
+出现此异常时,必须释放编解码器,因为它已转入终止状态。
+
+</li>
+<li>新增了 {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} 接口,用于获取有关支持的编解码器实例最大并发数量的提示。
+
+</li>
+<li>新增了 {@code MediaPlayer.setPlaybackParams()} 方法,用于设置快动作回放或慢动作回放的媒体回放速率。
+此外,它还会随视频一起自动拉长或加速音频回放。
+</li>
+</ul>
+
+<h2 id="camera">相机功能</h2>
+<p>本预览版提供了下列用于访问相机闪光灯和相机图像再处理的新 API:
+</p>
+
+<h3 id="flashlight">闪光灯 API</h3>
+<p>如果相机设备带有闪光灯,您可以通过调用 {@code CameraManager.setTorchMode()}
+ 方法,在不打开相机设备的情况下打开或关闭闪光灯的火炬模式。应用对闪光灯或相机设备不享有独占所有权。
+每当相机设备不可用,或者开启火炬的其他相机资源不可用时,火炬模式即会被关闭并变为不可用状态。
+
+其他应用也可调用 {@code setTorchMode()} 来关闭火炬模式。
+当最后一个开启火炬模式的应用关闭时,火炬模式就会被关闭。
+</p>
+
+<p>您可以注册一个回调,通过调用
+{@code CameraManager.registerTorchCallback()} 方法接收有关火炬模式状态的通知。第一次注册回调时,系统会立即调用它,并返回所有当前已知配备闪光灯的相机设备的火炬模式状态。
+
+如果成功开启或关闭火炬模式,系统会调用
+{@code CameraManager.TorchCallback.onTorchModeChanged()} 方法。</p>
+
+<h3 id="reprocessing">再处理 API</h3>
+<p>{@link android.hardware.camera2 Camera2} API 进行了扩展,以支持 YUV 和专用不透明格式图像再处理。
+您的应用通过 {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES} 确定再处理功能是否可用。
+如果设备支持再处理,您可以通过调用
+{@code CameraDevice.createReprocessableCaptureSession()} 创建一个可再处理的相机捕获会话并创建输入缓冲区再处理请求。
+
+</p>
+
+<p>使用 {@code ImageWriter} 类可将输入缓冲区流与相机再处理输入相连。
+如需获得空白缓冲区,请遵循以下编程模型:</p>
+
+<ol>
+<li>调用 {@code ImageWriter.dequeueInputImage()} 方法。</li>
+<li>在输入缓冲区中填充数据。</li>
+<li>通过调用 {@code ImageWriter.queueInputImage()} 方法将缓冲区发送至相机。</li>
+</ol>
+
+<p>如果您将 {@code ImageWriter} 对象与
+{@code android.graphics.ImageFormat.PRIVATE} 图像一起使用,您的应用并不能直接访问图像数据。
+请改为调用 {@code ImageWriter.queueInputImage()} 方法,将 {@code ImageFormat.PRIVATE} 图像直接传递给
+{@code ImageWriter},而无需进行任何缓冲区复制。
+</p>
+
+<p>{@code ImageReader} 类现在支持 {@code android.graphics.ImageFormat.PRIVATE} 格式图像流。
+凭借此支持特性,您的应用可使
+{@code ImageReader} 输出图像保持为循环图像队列,还可选择一个或多个图像并将其发送给
+{@code ImageWriter} 进行相机再处理。</p>
+
+<h2 id="afw">Android for Work 功能</h2>
+<p>本预览版提供了下列用于 Android for Work 的新 API:</p>
+<ul>
+ <li><strong>用于企业所有、单一用途设备的增强型控件</strong>:现在,设备所有者可以通过控制以下设置来改善企业所有、单一用途 (COSU) 设备的管理:
+
+
+ <ul>
+ <li>通过
+{@code DevicePolicyManager.setKeyguardEnabledState()} 方法禁用或重新启用键盘锁。</li>
+ <li>通过
+{@code DevicePolicyManager.setStatusBarEnabledState()} 方法禁用或重新启用状态栏(包括快速设置、通知以及启动 Google Now 的向上划动手势)。
+</li>
+ <li>通过 {@link android.os.UserManager} 常量
+{@code DISALLOW_SAFE_BOOT} 禁用或重新启用安全启动</li>
+ <li>通过
+{@link android.provider.Settings.Global} 常量 {@code STAY_ON_WHILE_PLUGGED_IN} 防止屏幕在插入电源的情况下关闭。</li>
+ </ul>
+ </li>
+ <li><strong>设备所有者静默式安装和卸载应用</strong>:现在,设备所有者可使用 {@link android.content.pm.PackageInstaller}
+ API 在不依赖 Google Play for Work 的情况下静默式安装和卸载应用。
+现在,您可以通过设备所有者配置设备,从而无需用户干预即可获取并安装应用。
+此功能可用于在不激活 Google 帐户的情况下实现信息亭或其他此类设备的一键式配置。
+</li>
+<li><strong>静默式企业证书访问</strong>:现在,当应用调用
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()} 时,配置文件所有者或设备所有者可以在系统提示用户选择证书前调用 {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} 方法,静默式向发出请求的应用提供别名。
+
+
+此功能让您可以在无需用户干预的情况下授予托管应用访问证书的权限。
+</li>
+<li><strong>自动接受系统更新</strong>。现在,设备所有者可以通过
+{@code DevicePolicyManager.setSystemUpdatePolicy()} 设置一个系统更新政策来自动接受系统更新(例如对于信息亭设备),或者推迟更新并在至多 30 天的时间内防止用户获取更新。
+
+此外,管理员还可设置每日必须获取更新的时间窗口,例如在信息亭设备无人使用的时段。
+有可用的系统更新时,系统会检查工作政策控制器应用是否设置了系统更新政策,并相应地执行操作。
+
+
+</li>
+<li>
+<strong>授权证书安装</strong>:配置文件所有者或设备所有者现在可以授权第三方应用调用以下 {@link android.app.admin.DevicePolicyManager} 证书管理 API:
+
+
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>企业恢复出厂设置保护</strong>:现在,配置设备所有者时,您可以通过设置
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} 捆绑包配置参数来解锁恢复出厂设置保护 (FRP)。
+在重置设备以解锁 FRP 和配置设备之后,NFC 编程器应用可提供这些参数,而无需事先配置 Google 帐户。
+
+如果您不修改这些参数,FRP 仍然发挥作用,必须使用之前激活的 Google 凭据方可激活设备。
+
+
+<p>此外,通过对 Google Play 服务设置应用限制,设备所有者可以指定用于 FRP 解锁的备用 Google 帐户,以替代在设备上激活的 Google 帐户。
+</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>数据使用情况跟踪</strong>。现在,配置文件所有者或设备所有者可以利用新增的
+{@code android.app.usage.NetworkStatsManager} 方法查询<strong>设置 > 数据使用情况</strong>中显示的数据使用情况统计信息。
+配置文件所有者会被自动授予查询其管理的配置文件相关数据的权限,而设备所有者则被授予对其管理的主要用户使用情况数据的访问权。
+
+</li>
+<li><strong>运行时权限管理</strong>:
+<p>配置文件所有者或设备所有者可以利用
+{@code DevicePolicyManager.setPermissionPolicy()} 设置适用于所有应用全部运行时请求的权限政策,以提示用户照常授予权限,或自动以静默方式授予或拒绝权限。
+
+如果设置后一种政策,则用户将无法修改配置文件所有者或设备所有者在应用权限屏幕的<strong>设置</strong>内所做的选择。
+
+</p></li>
+<li><strong>“设置”中的 VPN</strong>:现在,<strong>设置 > 更多 > VPN</strong> 中会显示 VPN 应用。此外,现在,关于 VPN 使用情况的通知取决于该 VPN 的配置方式。
+
+
+对于配置文件所有者,通知取决于该 VPN 是针对托管配置文件、个人配置文件还是同时针对这两者进行配置。
+对于设备所有者,通知取决于 VPN 是否针对整个设备进行配置。
+</li>
+<li><strong>工作状态通知</strong>:现在,每当来自托管配置文件的应用具有前台活动时,状态栏就会出现一个公文包图标。
+此外,如果设备直接解锁到托管配置文件中某个应用的活动,则会显示一个 Toast,通知用户他们位于托管配置文件内。
+
+
+</li>
+</ul>
+
+<p class="note">
+ 如需详细了解 M 开发者预览版中的所有 API 变更,请参阅 <a href="{@docRoot}preview/download.html">API 差异报告</a>。
+</p>
diff --git a/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd b/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd
new file mode 100644
index 0000000..39494b9
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=行为变更
+page.keywords=预览版,sdk,兼容性
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本文内容</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">运行时权限</a></li>
+ <li><a href="#behavior-power">节能优化</a>
+ <ol>
+ <li><a href="#behavior-doze">打盹</a></li>
+ <li><a href="#behavior-app-standby">应用待机</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">可采用的存储设备</a></li>
+ <li><a href="#behavior-apache-http-client">取消支持 Apache HTTP 客户端</a></li>
+ <li><a href="#behavior-audiomanager-Changes">音频管理器变更</a></li>
+ <li><a href="#behavior-test-selection">文本选择</a></li>
+ <li><a href="#behavior-keystore">Android 密钥库变更</a></li>
+ <li><a href="#behavior-network">Wi-Fi 和网络连接变更</a></li>
+ <li><a href="#behavior-camera">相机服务变更</a></li>
+ <li><a href="#behavior-art-runtime">ART 运行时</a></li>
+ <li><a href="#behavior-apk-validation">APK 验证</a></li>
+ <li><a href="#behavior-afw">Android for Work 变更</a></li>
+</ol>
+
+<h2>API 差异</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API 级别 22 至 M 预览版»</a> </li>
+</ol>
+
+
+<h2>另请参阅</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">M 开发者预览版 API 概览</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M 开发者预览版除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。
+本文重点介绍您应该了解并在开发应用时加以考虑的一些重要变更。
+</p>
+
+<p>如果您之前发布过 Android 应用,请注意您的应用可能受到这些平台变更的影响。
+</p>
+
+<h2 id="behavior-runtime-permissions">运行时权限</h1>
+<p>本预览版引入了一种新的权限模型,如今,用户可直接在运行时管理应用权限。
+这种模型让用户能够更好地了解和控制权限,同时为应用开发者精简了安装和自动更新过程。用户可为所安装的各个应用分别授予或撤销权限。
+
+ </p>
+
+<p>对于面向 M 预览版开发的应用,请务必在运行时检查和请求权限。
+如需确定您的应用是否已被授予权限,请调用新增的 {@code Context.checkSelfPermission()} 方法。
+如需请求权限,请调用新增的
+{@code Activity.requestPermission()} 方法。即使您的应用不是针对 M 开发的,您也应该在新权限模型下测试您的应用。
+</p>
+
+<p>如需了解有关在您的应用中支持新权限模型的详细信息,请参阅开发者预览版的<a href="{@docRoot}preview/features/runtime-permissions.html">权限</a>页面。
+
+如需了解如何评估新模型对应用的影响,请参阅<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">测试指南</a>。
+</p>
+
+<h2 id="behavior-power">节能优化</h2>
+<p>本预览版引入了针对空闲设备和应用的最新节能优化技术。</p>
+
+<h3 id="behavior-doze">打盹</h3>
+<p>如果设备未插入电源,并在屏幕关闭后的一段时间内保持不活动状态,则会进入<em>打盹</em>模式,在该模式下设备会尝试让系统保持休眠状态。
+在该模式下,设备会定期短时间恢复正常工作,以便进行应用同步,还可让系统执行任何挂起的操作。
+
+</p>
+
+<p>在打盹模式下,您的应用会受到以下限制:</p>
+<ul>
+<li>网络访问被禁用,除非您的应用获得高优先级 Google Cloud Messaging 操作消息 (tickle)。
+</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">唤醒锁</a>会被忽略。</li>
+<li>通过 {@link android.app.AlarmManager} 类设置的闹铃会被禁用,但通过 {@link android.app.AlarmManager#setAlarmClock setAlarmClock()} 方法和 {@code AlarmManager.setAndAllowWhileIdle()} 方法设置的闹铃除外。
+
+</li>
+<li>不执行 WiFi 扫描</li>
+<li>不允许运行同步适配器和 {@link android.app.job.JobScheduler} 的同步和作业。
+</li>
+</ul>
+</p>
+<p>当设备退出打盹模式时,它会执行任何挂起的作业和同步。</p>
+<p>您可以通过将运行 M 预览版的设备与您的开发计算机相连,并调用以下命令来测试此功能:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>注</strong>:即将推出的
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+ Google Cloud Messaging</a> 版本允许您指定高优先级消息。
+如果您的应用收到高优先级 GCM 消息,即使设备处于打盹模式,系统也会向其授予短时间的网络访问权限。
+
+</p>
+
+<p>如需了解在您的应用中测试打盹模式的技巧,请参阅
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">测试指南</a>。
+ </p>
+
+<h3 id="behavior-app-standby">应用待机</h3>
+<p>使用本预览版时,系统会在应用未被主动使用时确定其处于空闲状态。
+除非系统检测到以下信号之一,否则将在一段时间后将您的应用视为处于空闲状态:
+</p>
+
+<ul>
+<li>用户显式启动应用。</li>
+<li>应用当前有一个进程位于前台(表现为活动或前台服务形式,或被另一活动或前台服务占用)。
+</li>
+<li>应用生成用户可在锁屏或通知托盘中看到的通知。
+</li>
+<li>用户通过<strong>设置</strong>显式请求不对应用进行优化。
+</li>
+</ul>
+
+<p>如果设备未插入电源,系统会将被视为处于空闲状态的应用的网络访问禁用,并暂停其同步和作业。
+当设备插入电源时,系统将允许这些应用访问网络并执行任何挂起的作业和同步。
+如果设备长时间处于空闲状态,系统将按每天大约一次的频率允许空闲状态的应用访问网络。
+</p>
+
+<p>您可以通过将运行 M 预览版的设备与您的开发计算机相连,并调用以下命令来测试此功能:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>注</strong>:即将推出的
+<a href="https://developers.google.com/cloud-messaging/" class="external-link">
+ Google Cloud Messaging</a> (GCM) 版本允许您指定高优先级消息。
+如果您的应用收到高优先级 GCM 消息,即使其处于空闲状态,也会被授予短时间的网络访问权限。
+
+</p>
+
+<p>如需了解在您的应用中测试应用待机的技巧,请参阅
+<a href="{@docRoot}preview/testing/guide.html#doze-standby">测试指南</a>。
+ </p>
+
+<h2 id="behavior-adoptable-storage">可采用的存储设备</h2>
+<p>
+使用本预览版时,用户可以<em>采用</em> SD 卡等外部存储设备。采用外部存储设备可加密和格式化设备,使其具有类似内部存储设备的行为。
+用户可以利用此特性在存储设备之间移动应用及其私有数据。
+移动应用时,系统会遵守清单文件中的
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
+ 首选项。
+</p>
+
+<p>请注意,在内部存储设备与外部存储设备之间移动应用时,如果您的应用访问以下 API 或字段,它们返回的文件路径将会动态变化。郑重建议:在生成文件路径时,请始终动态调用这些 API。请勿使用硬编码文件路径或之前生成的永久性完全限定文件路径。
+
+
+</p>
+
+<ul>
+<li>{@link android.content.Context} 方法:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>{@link android.content.pm.ApplicationInfo} 字段:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>如需在开发者预览版中调试此功能,您可以将一个 USB 驱动器通过一根 USB On-The-Go (OTG) 电缆连接到 Android 设备并运行以下命令启用对该 USB 驱动器的采用:
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">取消支持 Apache HTTP 客户端</h2>
+<p>本预览版取消了对 Apache HTTP 客户端的支持。如果您的应用使用该客户端,并以 Android 2.3(API 级别 9)或更高版本为目标平台,请改用 {@link java.net.HttpURLConnection} 类。
+
+此 API 效率更高,因为它可以通过透明压缩和响应缓存减少网络使用,并可最大限度降低耗电量。
+如需继续使用 Apache HTTP API,您必须先在 {@code build.gradle} 文件中声明以下编译时依赖项:
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android 正在从使用 OpenSSL 库转向使用
+<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
+ 库。如果您要在应用中使用 Android NDK,请勿链接到并非 NDK API 组成部分的加密库,如 {@code libcrypto.so} 和 {@code libssl.so}。
+这些库并非公共 API,可能会在不同版本和设备上毫无征兆地发生变化或出现故障。此外,您还可能让自己暴露在安全漏洞的风险之下。
+
+请改为修改原生代码,以通过 JNI 调用 Java 加密 API,或静态链接到您选择的加密库。
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">音频管理器变更</h2>
+<p>不再支持通过 {@link android.media.AudioManager}
+ 类直接设置音量或将特定音频流静音。{@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} 方法已弃用,您应该改为调用
+{@code AudioManager.requestAudioFocus()} 方法。类似地,
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} 方法也已弃用,请改为调用 {@code AudioManager.adjustStreamVolume()} 方法并传入方向值 {@code ADJUST_MUTE} 或 {@code ADJUST_UNMUTE}。
+
+</p>
+
+<h2 id="behavior-test-selection">文本选择</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>现在,当用户在您的应用中选择文本时,您可以在一个<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">浮动工具栏</a>中显示“剪切”<em></em>、“复制”<em></em>和“粘贴”<em></em>等文本选择操作。
+
+其在用户交互实现上与<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">为单个视图启用上下文操作模式</a>中所述的上下文操作栏类似。
+
+
+</p>
+
+<p>如需实现可用于文本选择的浮动工具栏,请在您的现有应用中做出以下更改:
+</p>
+<ol>
+<li>在 {@link android.view.View} 对象或 {@link android.app.Activity} 对象中,将
+{@link android.view.ActionMode} 调用从
+{@code startActionMode(Callback)} 更改为 {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}。</li>
+<li>改为使用 {@code ActionMode.Callback} 的现有实现扩展
+{@code ActionMode.Callback2}。</li>
+<li>替代 {@code Callback2.onGetContentRect()} 方法,用于提供 {@link android.graphics.Rect} 内容对象(如文本选择矩形)在视图中的坐标。
+</li>
+<li>如果矩形的定位不再有效,并且这是唯一需要声明为无效的元素,请调用 {@code ActionMode.invalidateContentRect()} 方法。
+</li>
+</ol>
+
+<p>请注意,如果您使用 <a href="{@docRoot}tools/support-library/index.html">
+ Android Support Library</a> 22.2 修订版,浮动工具栏不向后兼容,默认情况下 appcompat 会获得对 {@link android.view.ActionMode} 对象的控制权。
+
+这会禁止显示浮动工具栏。如需在
+{@link android.support.v7.app.AppCompatActivity} 中启用
+{@link android.view.ActionMode} 支持,请调用
+{@code android.support.v7.app.AppCompatActivity.getDelegate()},然后对返回的
+{@link android.support.v7.app.AppCompatDelegate} 调用
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()},并将输入参数设置为 {@code false}。
+此调用会将 {@link android.view.ActionMode} 对象的控制权交还给框架。
+在运行 M 预览版的设备上,框架可以支持
+{@link android.support.v7.app.ActionBar} 模式或浮动工具栏模式;而在运行 M 预览版之前版本的设备上,框架仅支持 {@link android.support.v7.app.ActionBar} 模式。
+</p>
+
+<h2 id="behavior-keystore">Android 密钥库变更</h2>
+<p>使用本预览版时,
+<a href="{@docRoot}training/articles/keystore.html">Android 密钥库提供程序</a>不再支持 DSA,
+但仍支持 ECDSA。</p>
+
+<p>禁用或重置安全锁屏时(例如,由用户或设备管理员执行此类操作时),系统将不再删除需要闲时加密的密钥,
+但在上述事件期间会删除需要闲时加密的密钥。
+</p>
+
+<h2 id="behavior-network">Wi-Fi 和网络连接变更</h2>
+
+<p>本预览版对 Wi-Fi 和网络连接 API 引入了以下行为变更。</p>
+<ul>
+<li>现在,您的应用只能更改由您创建的 {@link android.net.wifi.WifiConfiguration} 对象的状态。
+系统不允许您修改或删除由用户或其他应用创建的
+{@link android.net.wifi.WifiConfiguration} 对象;
+</li>
+<li>
+在之前的版本中,如果应用利用带有
+{@code disableAllOthers=true} 设置的
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} 强制设备连接特定 Wi-Fi 网络,设备将会断开与蜂窝数据网络等其他网络的连接。
+在本预览版中,设备不再断开与上述其他网络的连接。如果您的应用的 {@code targetSdkVersion} 为 {@code “20”} 或更低,则会固定连接所选 Wi-Fi 网络。
+
+如果您的应用的 {@code targetSdkVersion} 为 {@code “21”} 或更高,请使用多网络 API(如
+{@link android.net.Network#openConnection(java.net.URL) openConnection()} 、
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} 和新增的
+{@code ConnectivityManager.bindProcessToNetwork()} 方法)来确保通过所选网络传送网络流量。
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">相机服务变更</h2>
+<p>在本预览版中,相机服务中共享资源的访问模式已从之前的“先到先得”访问模式更改为高优先级进程优先的访问模式。
+
+对服务行为的变更包括:</p>
+<ul>
+<li>根据客户端应用进程的“优先级”授予对相机子系统资源的访问权,包括打开和配置相机设备。
+带有对用户可见活动或前台活动的应用进程一般会被授予较高的优先级,从而使相机资源的获取和使用更加可靠;
+
+</li>
+<li>当高优先级的应用尝试使用相机时,系统可能会“驱逐”正在使用相机客户端的低优先级应用。
+在已弃用的 {@link android.hardware.Camera} API 中,这会导致系统为被驱逐的客户端调用
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}。
+
+在 {@link android.hardware.camera2 Camera2} API 中,这会导致系统为被驱逐的客户端调用
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()};
+</li>
+<li>在配备相应相机硬件的设备上,不同的应用进程可同时独立打开和使用不同的相机设备。
+但现在,如果在多进程用例中同时访问相机会造成任何打开的相机设备的性能或能力严重下降,相机服务会检测到这种情况并禁止同时访问。
+
+即使并没有其他应用直接尝试访问同一相机设备,此变更也可能导致低优先级客户端被“驱逐”。
+
+
+</li>
+<li>
+更改当前用户会导致之前用户帐户拥有的应用内活动相机客户端被驱逐。
+对相机的访问仅限于访问当前设备用户拥有的用户个人资料。举例来说,这意味着,当用户切换到其他帐户后,“来宾”帐户实际上无法让使用相机子系统的进程保持运行状态。
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">ART 运行时</h2>
+<p>ART 运行时现在可正确实现
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 方法的访问规则。此变更修正了之前版本中 Dalvik 无法正确检查访问规则的问题。如果您的应用使用
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 方法,并且您想替代访问检查,请调用
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} 方法(将输入参数设置为 {@code true})。
+
+
+
+如果您的应用使用
+<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat 库</a>或
+<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview 库</a>,则您必须更新应用以使用这些库的最新版本。
+否则,请务必更新从 XML 引用的任何自定义类,以便能够访问它们的类构造函数。
+</p>
+
+<p>本预览版更新了动态链接程序的行为。动态链接程序现在可以识别库的 {@code soname} 与其路径之间的差异(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
+公开 bug 6670</a>),并且现在已实现了按 {@code soname} 搜索。
+
+
+之前包含错误的 {@code DT_NEEDED} 条目(通常是开发计算机文件系统上的绝对路径)却仍工作正常的应用,如今可能会出现加载失败。
+</p>
+
+<p>现已正确实现 {@code dlopen(3) RTLD_LOCAL} 标志。请注意,
+{@code RTLD_LOCAL} 是默认值,因此不显式使用
+{@code RTLD_LOCAL} 的 {@code dlopen(3)} 调用将受到影响(除非您的应用显式使用 {@code RTLD_GLOBAL})。使用
+{@code RTLD_LOCAL} 时,在随后通过调用
+{@code dlopen(3)} 加载的库中并不能使用这些符号(这与由 {@code DT_NEEDED} 条目引用的情况截然不同)。</p>
+</p>
+
+<h2 id="behavior-apk-validation">APK 验证</h2>
+<p>该平台现在执行的 APK 验证更为严格。如果在清单文件中声明的文件在 APK 中并不存在,该 APK 将被视为已损坏。
+移除任何内容后必须重新签署 APK。
+</p>
+
+<h2 id="behavior-afw">Android for Work 变更</h2>
+<p>本预览版包含下列针对 Android for Work 的行为变更:</p>
+<ul>
+<li><strong>个人上下文中的工作联系人。</strong>Google Dialer Call Log 现在会在用户查看通话记录时显示工作联系人。将 {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} 设置为 {@code true} 可在 Google Dialer Call Log 中隐藏托管配置文件联系人。
+
+
+仅当您将 {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} 设置为 {@code false} 时,才可以通过蓝牙将工作联系人随个人联系人一起显示给设备。
+
+默认情况下,它设置为 {@code true}。
+
+</li>
+<li><strong>WiFi 配置移除</strong>:现在,当删除某个托管配置文件时,将会移除由配置文件所有者添加的 WiFi 配置(例如,通过调用
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()} 方法添加的配置);
+</li>
+<li><strong>WiFi 配置锁定</strong>:用户无法再修改或删除任何由活动设备所有者创建的 WiFi 配置。
+用户仍可创建和修改其自己的 WiFi 配置,前提是尚未针对该用户设置 {@link android.os.UserManager} 常量
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI}。
+</li>
+<li><strong>通过添加 Google 帐户下载工作策略控制器</strong>向托管环境以外的设备添加需要通过工作策略控制器 (WPC) 管理的 Google 帐户时,帐户添加流程现在会提示用户安装相应的 WPC。在设备初始设置向导中通过<strong>设置 > 帐户</strong>添加帐户时,也会出现此行为。
+
+
+
+</li>
+<li><strong>对特定 DevicePolicyManager API 行为的变更</strong>:调用 {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} 方法只会影响调用该方法的用户的相机;从托管配置文件调用它不会影响主用户运行的相机应用。
+
+
+此外,
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} 方法现在除了可供设备所有者使用外,还可供配置文件所有者使用。
+配置文件所有者可设置以下键盘锁限制:
+
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} 和
+{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT},它们影响配置文件上级用户的键盘锁设置。
+</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS},它只影响应用在托管配置文件中生成的通知。
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd b/docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..94a6212
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=权限
+page.tags=预览资源, androidm
+page.keywords=权限, 运行时, 预览
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>内容快览</h2>
+ <ul>
+ <li>如果您的应用主要面向 M 预览版 SDK,则会在运行时(而非安装时)提示用户授予权限。
+</li>
+ <li>用户可以随时从应用“设置”屏幕撤销权限。
+</li>
+ <li>每次运行时,应用均需检查自身是否具备所需的权限。
+</li>
+ </ul>
+
+ <h2>本文内容</h2>
+ <ol>
+ <li><a href="#overview">概览</a></li>
+ <li><a href="#coding">为运行时权限编码</a></li>
+ <li><a href="#testing">测试运行时权限</a></li>
+ <li><a href="#best-practices">最佳做法</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ M 开发者预览版引入了一种新的应用权限模型,旨在简化用户安装和升级应用的过程。
+如果在 M 预览版上运行的应用支持新权限模型,则用户无需在安装或升级应用时授予任何权限。相反,应用会根据需要请求权限,且系统将向用户显示一个请求权限的对话框。
+
+
+
+
+</p>
+
+<p>
+ 如果应用支持新权限模型,则仍可在运行旧版 Android 的设备上使用旧权限模型安装并运行此应用。
+
+
+</p>
+
+<h2 id="overview">
+ 概览
+</h2>
+
+<p>
+ 通过 M 开发者预览版,该平台引入了新的应用权限模型。
+以下概述了此新模型的主要组件:
+</p>
+
+<ul>
+ <li>
+ <strong>声明权限:</strong>应用使用清单文件声明其所需的所有权限,就像在早期的 Android 平台中一样。
+
+ </li>
+
+ <li>
+ <strong>权限组:</strong>权限根据相应的功能分为若干
+<em>权限组</em>。例如,
+<code>CONTACTS</code> 权限组包含读取和写入用户联系人和个人资料信息的权限。
+
+ </li>
+
+ <li>
+ <p><strong>安装时授予的有限权限:</strong>当用户安装或更新应用时,系统将授予应用所请求的属于 {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} 的所有权限。
+
+
+ 例如,闹铃和 Internet 权限属于 {@link
+ android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL},因此系统将在安装应用时自动授予这些权限。
+
+ </p>
+
+ <p>此外,系统还可以授予应用签名和系统权限,如<a href="#system-apps">系统应用和签名权限</a>中所述。
+
+系统不会在安装应用时提示用户授予任何权限。<em></em>
+</p>
+ </li>
+
+ <li>
+ <strong>用户在运行时授予权限:</strong>当应用请求权限时,系统将向用户显示一个对话框,然后调用应用的回调函数来通知它是否已授予权限。
+
+如果用户授予某项权限,则应用将获得应用清单文件中声明的、该权限功能区域中的所有权限。
+
+
+ </li>
+
+</ul>
+
+<p>
+ 对于需要权限的功能,此权限模型将改变应用的行为方式。
+以下概述了您调整此模型时所应遵循的开发实践:
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>始终检查权限:</strong>当应用必须执行任何需要权限的操作时,应先检查它是否已具备该权限。
+
+如果没有,则请求授予该权限。
+
+ </li>
+
+ <li>
+ <strong>妥善处理权限不足的情况:</strong>如果应用未被授予适当的权限,则应正常处理失败情况。
+
+ 例如,如果只有新增的功能需要该权限,则应用可以禁用该功能。
+如果该权限对于应用正常运行至关重要,则应用可能会禁用其所有功能,并通知用户需要授予该权限。
+
+
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>图 1.</strong>应用“设置”中的“权限”屏幕。
+ </p>
+ </div>
+
+ <li>
+ <strong>权限可撤销:</strong>用户可以随时撤销应用的权限。
+即使用户禁用应用的权限,应用也不会收到通知。<em></em>
+再次强调:您的应用应在执行任何受限操作之前验证是否具备所需的权限。
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>注:</strong>如果应用主要面向 M 开发者预览版,则必须使用新权限模型。
+<em></em>
+</p>
+
+<p>
+ 截至 M 开发者预览版发布,并非所有 Google 应用均已完全实现新权限模型。
+Google 会在 M 开发者预览版运行期间更新这些应用,以便严格遵守权限切换设置。
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong>如果您的应用拥有自己的 API 接口,请先确保调用方具备访问该数据所需的必要权限,然后再代理权限。
+
+
+</p>
+
+<h3 id="system-apps">
+ 系统应用和签名权限
+</h3>
+
+<p>
+ 通常,当用户安装应用时,系统仅授予应用
+ {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL}。但在某些情况下,系统将授予应用更多权限:
+
+</p>
+
+<ul>
+ <li>如果应用是系统映像的一部分,则系统会自动授予该应用清单文件中列出的所有权限。
+
+ </li>
+
+ <li>如果应用请求提供清单文件中属于 {@link
+ android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} 的权限,且该应用已使用与声明这些权限的应用相同的证书进行签名,则系统将在安装请求权限的应用时向其授予这些权限。
+
+
+
+ </li>
+</ul>
+
+<p>
+ 在这两种情况下,用户仍可随时撤销权限,具体方法是:转到系统的<strong>设置</strong>屏幕,然后选择<strong>应用 ></strong>
+
+ <i>应用名称</i> <strong>> 权限</strong>。应用应在运行时继续检查权限,并根据需要请求权限。
+
+
+</p>
+
+<h3 id="compatibility">
+ 前后兼容性
+</h3>
+
+<p>
+ 如果应用并非面向 M 开发者预览版,则即使是在 M 预览版设备上,该应用也会继续使用旧权限模型。
+当用户安装应用时,系统将要求用户授予应用清单文件中列出的所有权限。
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong>在运行 M 开发者预览版的设备上,用户可以从应用的“设置”屏幕禁用任何应用(包括旧版应用)的权限。
+
+如果用户禁用某旧版应用的权限,则系统将以静默方式禁用相应的功能。
+当应用尝试执行需要该权限的操作时,该操作不一定会导致出现异常。
+
+相反,它可能会返回空数据集、报告错误或以其他方式表现出异常行为。
+例如,如果您未经许可查询日历,则该方法会返回空数据集。
+
+</p>
+
+<p>
+ 如果您在未运行 M 预览版的设备上使用新权限模型安装应用,则系统将采用与其他任何应用相同的方式处理:系统会在安装应用时要求用户授予声明的所有权限。
+
+
+
+</p>
+
+<p class="note">
+ <strong>注:</strong>对于预览版本,您必须将最低 SDK 版本设置为 M 预览版 SDK,才可使用预览版 SDK 进行编译。
+这意味着在开发者预览版运行期间,您无法在旧版平台上测试此类应用。
+
+
+</p>
+
+<h3 id="perms-vs-intents">权限与意向的比较</h3>
+
+<p>
+ 许多情况下,您可以使用以下两种方式之一来让您的应用执行某项任务。
+您可以将应用设置为请求执行操作本身所需的权限。
+或者,您可以将应用设置为通过传送意向,让其他应用来执行任务。
+
+</p>
+
+<p>
+ 例如,假设应用需要能够使用设备相机拍摄照片。
+应用可以请求
+<code>android.permission.CAMERA</code> 权限,以便允许其直接访问相机。
+然后,应用将使用 Camera API 控制相机并拍摄照片。
+利用此方法,您的应用能够完全控制摄影过程,并支持您将相机 UI 合并至应用中。
+
+
+</p>
+
+<p>
+ 但是,如果您无需此类控制,则可仅使用 {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} 意向来请求图像。
+启动该意向时,系统会提示用户选择相机应用(如果没有默认相机应用),然后该应用将拍摄照片。
+
+该相机应用会将照片返回给应用的 {@link
+ android.app.Activity#onActivityResult onActivityResult()} 方法。
+</p>
+
+<p>
+ 同样,如果您需要打电话、访问用户的联系人或要执行其他操作,则可通过创建适当的意向来完成,或者您可以请求相应的权限并直接访问相应的对象。
+
+每种方法各有优缺点。
+
+</p>
+
+<p>
+ 如果使用权限:
+</p>
+
+<ul>
+ <li>应用可在您执行操作时完全控制用户体验。
+但是,如此广泛的控制会增加任务的复杂性,因为您需要设计适当的 UI。
+
+ </li>
+
+ <li>当您首次执行操作时,系统会显示一次让用户授予权限的提示。
+之后,应用即可执行操作,不再需要用户进行其他交互。
+但是,如果用户不授予权限(或稍后撤销权限),则应用根本无法执行操作。
+
+
+ </li>
+</ul>
+
+<p>
+ 如果使用意向:
+</p>
+
+<ul>
+ <li>您无需为操作设计 UI。处理意向的应用将提供 UI。不过这意味着您无法控制用户体验。
+
+用户可以与您从未见过的应用进行交互。
+
+ </li>
+
+ <li>如果用户没有适用于操作的默认应用,则系统会提示用户选择应用。如果用户未指定默认处理程序,则必须在每次执行此操作时额外处理一个对话框。
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">为运行时权限编码</h2>
+
+<p>
+ 如果应用主要面向新的 M 开发者预览版,则您必须使用新权限模型。
+这意味着除了通过清单文件声明所需的权限以外,您还必须检查应用运行时是否已有相应的权限,如果没有,则需要请求权限。
+
+
+
+</p>
+
+<h3 id="enabling">
+ 启用新权限模型
+</h3>
+
+<p>
+ 要启用新的 M 开发者预览版权限模型,请将应用的
+<code>targetSdkVersion</code> 属性设置为 <code>"MNC"</code>,并将
+<code>compileSdkVersion</code> 设置为 <code>"android-MNC"</code>。这样可启用所有新的权限功能。
+
+</p>
+
+<p>
+ 对于预览版本,您必须将 <code>minSdkVersion</code> 设置为
+<code>"MNC"</code>,才能使用预览版 SDK 进行编译。
+</p>
+
+<h3 id="m-only-perm">
+ 指定仅用于 M 预览版的权限
+</h3>
+
+<p>
+ 您可以使用应用清单文件中的新 <code><uses-permission-sdk-m></code> 元素指明仅在 M 开发者预览版中需要某权限。
+如果您以这种方式声明权限,则每当在旧版设备上安装应用时,系统都不会提示用户或向应用授予权限。通过使用 <code><uses-permission-sdk-m></code>
+ 元素,您可以将新权限添加到更新后的应用版本,而不必强制用户在安装更新时授予权限。
+
+
+
+
+
+</p>
+
+<p>
+ 如果应用在已安装 M 开发者预览版的设备上运行,则
+<code><uses-permission-sdk-m></code> 的行为与
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 相同。
+ 系统不会在安装应用时提示用户授予任何权限,且应用将根据需要请求权限。
+
+</p>
+
+<h3 id="prompting">
+ 提示授予权限
+</h3>
+
+<p>
+ 如果应用使用新的 M 开发者预览版权限模型,则在运行 M 预览版的设备上首次启动应用时,系统不会要求用户授予所有权限。
+
+相反,应用将根据需要请求权限。
+当应用请求某权限时,系统会向用户显示一个对话框。
+
+</p>
+
+<p>
+ 如果应用在已安装 SDK 22 或更低版本的设备上运行,则应用将使用旧权限模型。
+当用户安装应用时,系统将提示他们授予应用在清单文件中请求的所有权限,但那些带有 <code><uses-permission-sdk-m></code> 标记的权限除外。
+
+
+</p>
+
+<h4 id="check-platform">检查运行应用的平台</h4>
+
+<p>
+ 只有运行 M 开发者预览版的设备支持此权限模型。
+在调用其中任何方法之前,应用均应通过检查 {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME} 的值来验证运行应用的平台。
+
+如果设备正在运行 M 开发者预览版,则
+{@link android.os.Build.VERSION#CODENAME CODENAME} 为 <code>"MNC"</code>。
+</p>
+
+<h4 id="check-for-permission">检查应用是否具备所需的权限</h4>
+
+<p>当用户尝试执行需要权限的操作时,应用将检查目前是否具备执行此操作所需的权限。
+为此,应用将调用
+<code>Context.checkSelfPermission(
+<i>permission_name</i>)</code>。即便知道用户已授予该权限,应用也应执行此检查,因为用户可以随时撤销应用的权限。
+
+
+例如,如果用户需要使用应用拍摄照片,则应用将调用
+<code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>。
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>表 1.</strong>权限和权限组。</p>
+<table>
+ <tr>
+ <th scope="col">权限组</th>
+ <th scope="col">权限</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">根据需要请求权限</h4>
+
+<p>如果应用尚无所需的权限,则应用将调用
+<code>Activity.requestPermissions(String[], int)</code> 方法,请求提供一项或多项适当的权限。
+应用将传递所需的一项或多项权限,以及整数“请求代码”。
+
+ 此方法异步运行:它会立即返回,并且在用户响应对话框之后,系统会使用结果调用应用的回调方法,将应用传递的相同“请求代码”传递到 <code>requestPermissions()</code>。
+
+
+</p>
+
+ <p>以下代码检查应用是否具备读取用户联系人所需的权限,并根据需要请求该权限:
+</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">处理权限请求响应</h4>
+
+<p>
+ 当应用请求权限时,系统将向用户显示一个对话框。
+当用户响应时,系统将调用应用的
+<code>Activity.onRequestPermissionsResult(int, String[], int[])</code>
+,向其传递用户响应。应用需要替代该方法。回调会将您传递的相同请求代码传递给
+<code>requestPermissions()</code>。
+例如,如果应用请求
+<code>READ_CONTACTS</code> 访问权限,则可能采用以下回调方法:
+
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>如果用户授予权限,则系统会为应用授予应用清单文件为该功能区域列出的所有权限。
+如果用户拒绝请求,则您应采取适当的操作。
+例如,您可以禁用任何取决于此权限的菜单操作。
+
+ </li>
+</p>
+
+<p>
+ 当系统要求用户授予权限时,用户可以选择指示系统不再要求提供该权限。
+在这种情况下,当应用使用 <code>requestPermissions()</code> 请求该权限时,系统会立即拒绝此请求。
+
+在这种情况下,如果用户已再次明确拒绝您的请求,则系统会以同样的方式调用您的 <code>onRequestPermissionsResult()</code>。
+
+因此,您的应用不能假设用户采取了任何直接交互行为。
+
+</p>
+
+<h2 id="testing">测试运行时权限</h2>
+
+
+<p>
+ 如果应用主要面向 M 开发者预览版,则您必须测试它是否正确处理权限。
+您不能假设应用在运行时具备任何特定的权限。
+应用首次启动时,它可能没有任何权限,且用户可以随时撤销或恢复权限。
+
+
+</p>
+
+<p>
+ 您应测试应用,确保它在所有权限情况下均可正常运行。
+通过 M 预览版 SDK,我们提供了新的
+<a href="{@docRoot}tools/help/adb.html">Android
+ Debug Bridge (adb)</a> 命令,支持您使用需要尝试的任何权限设置测试应用。
+
+</p>
+
+<h3>
+ 新 adb 命令和选项
+</h3>
+
+<p>
+ M 预览版 SDK 平台工具提供了多个新命令,支持您测试应用处理权限的方式。
+
+</p>
+
+<h4>
+ 使用权限安装
+</h4>
+
+<p>
+ 您可以使用 <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a> 命令的新 <code>-g</code> 选项,该选项将安装应用并授予其清单文件中列出的所有权限:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ 授予和撤销权限
+</h4>
+
+<p>
+ 您可以使用新的 ADB <a href="{@docRoot}tools/help/adb.html#pm">软件包管理器 (pm)</a> 命令向已安装的应用授予权限和撤销其权限。此功能对于自动化测试非常有用。
+
+
+</p>
+
+<p>
+ 要授予权限,请使用软件包管理器的 <code>grant</code> 命令:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ 例如,要向录音授予 com.example.myapp 软件包权限,请使用以下命令:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ 要撤销权限,请使用软件包管理器的 <code>revoke</code> 命令:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">最佳做法</h2>
+
+<p>
+ 新权限模型为用户带来更流畅的体验,让他们能够更轻松地安装应用,并得心应手地使用应用的各项功能。
+
+为了充分利用该新模型,我们建议采用下列最佳做法。
+
+</p>
+
+
+<h3 id="bp-what-you-need">仅请求自己所需的权限</h3>
+
+<p>
+ 每次您请求权限时,实际上是在强迫用户作出决定。
+ 如果用户拒绝请求,则会减少应用的功能。
+ 您应尽量减少提出这些请求的次数。
+</p>
+
+<p>
+ 例如,应用往往可以通过使用
+<a href="{@docRoot}guide/components/intents-filters.html">意向</a>(而不是请求权限)获得所需的功能。
+如果应用需要使用手机的相机拍摄照片,则可使用
+ {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE} 意向。当应用执行该意向时,系统会提示用户选择已安装的相机应用拍摄照片。
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ 不要让用户感到无所适从
+</h3>
+
+<p>
+ 如果您让用户一次面对大量权限请求,用户可能会感到无所适从并因此退出应用。替代做法是,您应根据需要请求权限。
+
+
+</p>
+
+<p>
+ 某些情况下,您的应用可能绝对需要一项或多项权限。在这种情况下,合理的做法是,在应用启动之后立即请求所有权限。
+
+例如,如果您运行摄影应用,则该应用需要访问设备的相机。
+当用户首次启动该应用时,不会对请求使用相机所需的权限感到惊讶。
+
+但是,如果同一应用还具备与用户联系人共享照片的功能,则您不应在首次启动时请求用户提供该权限,<em></em>
+
+而是等到用户尝试使用“共享”功能之后,再请求该权限。
+
+</p>
+
+<p>
+ 如果应用提供了教程,则合理的做法是,在教程结束时请求提供应用的必要权限。
+
+</p>
+
+<h3 id="bp-explain">
+ 解释需要权限的原因
+</h3>
+
+<p>
+ 系统在您调用
+<code>requestPermissions()</code> 时显示的权限对话框将说明应用所需的权限,但不会解释为何需要这些权限。
+在某些情况下,用户可能会感到困惑。
+ 最好在调用 <code>requestPermissions()</code> 之前向用户解释应用需要权限的原因。
+
+</p>
+
+<p>
+ 例如,摄影应用可能需要使用位置服务,以便能够为照片添加地理标签。
+通常,用户可能不了解照片能够包含位置信息,并且对摄影应用想要了解具体位置感到不解。
+
+因此在这种情况下,应用最好在调用
+<code>requestPermissions()</code> 之前告知此功能的相关信息。<em></em>
+
+</p>
+
+<p>
+ 其中一种办法是将这些请求纳入应用教程。这样,教程可以依次显示应用的每项功能,并在显示每项功能时解释需要哪些相应的权限。
+
+例如,摄影应用的教程可以演示其“与您的联系人共享照片”功能,然后告知用户需要为应用授予权限以便其查看用户的联系人。
+
+
+然后,应用可以调用 <code>requestPermissions()</code>,要求用户提供该访问权限。
+当然,并非所有用户都会按照教程操作,因此您仍需在应用的正常操作期间检查和请求权限。
+
+
+</p>
diff --git a/docs/html-intl/intl/zh-cn/preview/overview.jd b/docs/html-intl/intl/zh-cn/preview/overview.jd
new file mode 100644
index 0000000..cebbf06
--- /dev/null
+++ b/docs/html-intl/intl/zh-cn/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=计划概览
+page.metaDescription=欢迎参加 Android M 开发者预览版计划。此计划将为您提供针对 Android 的下一版本测试和优化应用所需的所有功能。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ 欢迎使用 <strong>Android M 开发者预览版</strong>计划。此计划将为您提供针对 Android 的下一版本测试和优化应用所需的所有功能。
+
+它是一款免费软件。您仅需下载 M 开发者预览版工具即可立即使用。
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ 硬件和模拟器系统映像
+ </h5>
+
+ <p>
+ 在 Nexus 5、6、9 和 Player(适用于电视)以及模拟器中运行并测试应用。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 最新的平台代码
+ </h5>
+
+ <p>
+ 我们将在预览版期间提供多次更新,因此您将可以针对最新的平台变更测试您的应用。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 通过 OTA(空中下载技术)更新
+ </h5>
+
+ <p>
+ 在向设备刷入初始预览版后,即可通过 OTA 技术获取更新。
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 新行为和新功能
+ </h5>
+
+ <p>
+ 尽早做好支持新平台行为(例如新运行时权限模型和省电功能)的准备工作。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 为处理开发者反馈问题而设的优先窗口
+ </h5>
+
+ <p>
+ 在最初的几周里,我们将优先处理开发者报告的问题,以便尽快测试并提供反馈。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 反馈和支持
+ </h5>
+
+ <p>
+ 使用<a href="https://code.google.com/p/android-developer-preview/">问题跟踪器</a>向我们报告问题并提供反馈。
+ 与 <a href="http://g.co/dev/AndroidMDevPreview">M 开发者社区</a>中的其他开发者建立联系。
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ 时间表和更新
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M 开发者预览版从 5 月 28 日开始一直运行到最终 Android M SDK 发布为止。最终的 Android M SDK 将于 2015 年第三季度公众版发布之前不久发布。
+
+
+</p>
+
+<p>
+ 在开发阶段的各个里程碑,我们将为您的测试设备提供预览版更新。
+ 暂定的里程碑包括
+</p>
+
+<ul>
+ <li>
+ <strong>预览版 1</strong>(5 月底发布初始预览版);
+ </li>
+
+ <li>
+ <strong>预览版 2</strong>(6 月底/7 月初);
+ </li>
+
+ <li>
+ <strong>预览版 3</strong>(7 月底发布近乎最终版本)
+ </li>
+</ul>
+
+<p>
+ 这些更新将促进形成<strong>最终版本的 SDK</strong>(第三季度末),为 Android 新版本以及最终的系统行为和功能交付官方 API。
+
+
+</p>
+
+<p>
+ 如果您在 Android M 中进行测试和开发,我们郑重建议您随着预览版更新的发布,<strong>将开发环境保持为相应的最新版本</strong>。
+
+ 为了简化这一过程,我们将为已刷入预览版内部版本的设备提供<strong>空中下载 (OTA) 更新</strong>功能,并提供可供您手动下载并刷入的系统映像。
+
+
+</p>
+<p class="note">
+ <strong>注:</strong>最终的 SDK 和系统映像无法通过 OTA 交付,而是需要<strong>手动刷入</strong>到测试设备中。</strong>
+
+
+</p>
+
+<p>
+ 当有预览版更新可用时,我们将通过 <a href="http://android-developers.blogspot.com/">Android 开发者博客</a>、此站点以及 <a href="http://g.co/dev/AndroidMDevPreview">Android M 开发者社区</a>通知您。
+
+
+</p>
+
+<h2 id="preview_tools">
+ 预览版具有哪些功能?
+</h2>
+
+<p>
+ M 开发者预览版包括您在各种使用不同屏幕尺寸、网络技术、CPU/GPU 芯片和硬件架构的设备中测试现有应用所需的所有功能。
+
+
+</p>
+
+<h4>
+ SDK 工具
+</h4>
+
+<p>
+ 您可通过 <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> 中的 SDK 管理器下载这些组件:
+</p>
+
+<ul>
+ <li>M 开发者预览版 <strong>SDK 工具</strong>
+ </li>
+
+ <li>M 开发者预览版<strong>模拟器系统映像</strong>(32 位和 64 位)
+
+ </li>
+
+ <li>适用于 Android TV 的 M 开发者预览版<strong>模拟器系统映像</strong>(32 位)
+
+ </li>
+</ul>
+
+<h4>
+ 硬件系统映像
+</h4>
+
+<p>
+ 您可从<a href="download.html">“下载”页面</a>中下载这些供 Nexus 设备使用的硬件系统映像:
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE) “hammerhead” 设备系统映像
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong> “shamu” 设备系统映像
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi) “volantis” 设备系统映像
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV) “fugu” 设备系统映像
+ </li>
+</ul>
+
+<h4>
+ 文档和示例代码
+</h4>
+
+<p>
+ 以下文档资源有助于您了解预览版:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">设置 SDK</a>,提供入门指南的分步说明。
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">测试指南</a>和<a href="behavior-changes.html">行为变更</a>,带您了解主要测试领域。
+ </li>
+
+ <li>新 API 文档,包括 <a href="api-overview.html">API 概览</a>、可下载的 <a href="{@docRoot}preview/download.html#docs">API 参考资料</a>以及有关<a href="{@docRoot}preview/features/runtime-permissions.html">权限</a>、<a href="{@docRoot}preview/backup/index.html">应用备份</a>等主要功能的详细开发者指南。
+
+
+
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/samples.html">示例代码</a>,演示如何支持权限和其他新功能。
+
+ </li>
+
+ <li>
+ M 开发者预览版当前版本的<a href="{@docRoot}preview/support.html#release-notes">版本说明</a>,包括变更说明和差异报告。
+
+ </li>
+</ul>
+
+<h4>
+ 支持资源
+</h4>
+
+<p>
+ 在 M 开发者预览版中测试和开发时,您可使用以下支持资源:
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">M 开发者预览版问题跟踪器</a>是您的<strong>主要反馈渠道。</strong>
+
+您可通过问题跟踪器报告错误、性能问题和一般反馈。
+您还可检查<a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">已知问题</a>并找出解决方法步骤。
+
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 开发者社区</a>是一家 Google+ 社区。在此社区中,您可<strong>与其他使用 Android M 的开发者建立联系</strong>。您可以共享观察结果或想法,或查找 Android M 问题的解决方法。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 锁定目标、预览版 API 和发布
+</h2>
+
+<p>
+ Android M 开发者预览版是仅面向开发的版本,
+<strong>并不具有标准的 API 级别</strong>。如果您想选择拒绝通过兼容性行为测试您的应用(强烈推荐),则可将应用的 <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>
+ 设置为 <code>“MNC”</code>,从而锁定 M 开发者预览版。
+
+
+</p>
+
+<p>
+ Android M 开发者预览版提供<strong>预览 API</strong> 功能
+— 在最终的 SDK 发布之前,这些 API 都不是正式的 API。目前,最终的 SDK 计划于 2015 年第三季度发布。
+这意味着一段时期内,特别是该计划的最初几周内,
+<strong>API 可能会出现细微变化</strong>。
+我们会通过 Android M 开发者预览版的每次更新,为您提供一份变更摘要。
+
+</p>
+
+<p class="note">
+ 请注意,尽管预览版 API 可能会更改,但运行时权限和省电功能等基本系统行为仍保持稳定,可以立即用于测试。
+
+
+</p>
+
+<p>
+ 关于发布,Google Play 会<strong>禁止发布面向 M 开发者预览版的应用</strong>。
+当 Android M 最终版本 SDK 可用时,您可以锁定官方 Android M API 级别,并将应用发布至 Google Play。
+
+与此同时,如果您需要将针对 Android M 的应用分发给测试者,则可通过电子邮件或从您的站点直接下载实现这一点。
+
+
+</p>
+
+<h2 id="get_started">
+ 如何开始
+</h2>
+
+<p>
+ 要开始测试应用,请执行以下操作:
+</p>
+
+<ol>
+ <li>查看 <a href="{@docRoot}preview/api-overview.html">API 概览</a>和<a href="{@docRoot}preview/behavior-changes.html">行为变更</a>,大致了解新功能及其如何影响您的应用。
+
+特别地,您需要了解新的<a href="{@docRoot}preview/features/runtime-permissions.html">运行时权限</a>模型、省电功能和自动备份。
+
+
+ </li>
+
+ <li>遵循有关<a href="{@docRoot}preview/setup-sdk.html">设置预览版 SDK</a> 和配置测试设备的说明,来设置您的环境。
+
+
+ </li>
+
+ <li>遵循<a href="https://developers.google.com/android/nexus/images">刷入说明</a>,刷入 Nexus 5、6、9 和 Player 的最新 M 开发者预览版系统映像。
+
+为开发设备刷入系统映像后,预览版更新将通过无线 (OTA) 更新进行交付。</a>
+
+ </li>
+
+ <li>下载 <a href="{@docRoot}preview/download.html#docs">M 预览版 API 参考资料</a>和 <a href="{@docRoot}preview/samples.html">M 预览版示例</a>,更深入地了解新 API 功能以及如何在应用中使用这些功能。
+
+
+
+ </li>
+
+ <li>加入 <a href="http://g.co/dev/AndroidMDevPreview">Android M 开发者社区</a>,获取最新资讯并与使用新平台的其他开发者建立联系。
+
+
+ </li>
+</ol>
+
+<p>
+ 感谢您参加 Android M 开发者预览版计划!
+</p>
diff --git a/docs/html-intl/intl/zh-tw/preview/api-overview.jd b/docs/html-intl/intl/zh-tw/preview/api-overview.jd
new file mode 100644
index 0000000..f6c5696
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/api-overview.jd
@@ -0,0 +1,521 @@
+page.title=API 總覽
+page.keywords=預覽,sdk,相容性
+page.tags=previewresources, androidm
+sdk。platform.apiLevel=22-mnc
+page.image=images/cards/card-api-overview_16-9_2x.png
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本文件內容
+<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">顯示更多內容</span>
+ <span class="less" style="display:none">顯示較少內容</span></a></h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#app-linking">應用程式連結</a></li>
+ <li><a href="#backup">針對應用程式進行自動備份</a></li>
+ <li><a href="#authentication">驗證</a>
+ <ol>
+ <li><a href="#fingerprint-authentication">指紋驗證</a></li>
+ <li><a href="#confirm-credential">確認認證</a></li>
+ </ol>
+ </li>
+ <li><a href="#direct-share">直接分享</a></li>
+ <li><a href="#voice-interactions">語音互動</a></li>
+ <li><a href="#assist">協助 API</a></li>
+ <li><a href="#notifications">通知</a></li>
+ <li><a href="#bluetooth-stylus">藍牙手寫筆支援</a></li>
+ <li><a href="#ble-scanning">已改進藍牙低電量掃描</a></li>
+ <li><a href="#hotspot">無線基地台 2.0 版本 1 支援</a></li>
+ <li><a href="#4K-display">4K 顯示模式</a></li>
+ <li><a href="#behavior-themeable-colorstatelists">具備設計風格的 ColorStateList</a></li>
+ <li><a href="#audio">音訊功能</a></li>
+ <li><a href="#video">影片功能</a></li>
+ <li><a href="#camera">相機功能</a>
+ <ol>
+ <li><a href="#flashlight">閃光燈 API</a></li>
+ <li><a href="#reprocessing">相機重新處理</a></li>
+ </ol>
+ </li>
+ <li><a href="#afw">Android for Work 功能</a></li>
+</ol>
+
+<h2>API 差異</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API 級別 22 到 M 預覽版»</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>M 開發人員預覽版讓您能夠搶先查看即將發行的 Android 平台版本,這個版本將提供可供使用者和應用程式開發人員使用的新功能。
+
+本文件提供最值得受到矚目的 API 簡介。</p>
+
+<p>M 開發人員預覽版的適用對象是<strong>早期採用的開發人員</strong>和<strong>測試者</strong>。
+如果您對於如何影響 Android 架構方向深感興趣,請<a href="{@docRoot}preview/setup-sdk.html">嘗試使用 M 開發人員預覽版</a>,然後將您的意見反應傳送給我們!
+
+
+</p>
+
+<p class="caution"><strong>注意:</strong>請勿將使用 M 開發人員預覽版的應用程式發行到 Google Play 商店。
+</p>
+
+<p class="note"><strong>注意:</strong>本文件通常會參考 <a href="{@docRoot}">developer.android.com</a> 上尚未提供可用參考資料的類別和方法。
+這些 API 元素在本文件中的格式是 {@code code style} (不含超連結)。
+如需這些元素的 API 初稿文件,請下載<a href="{@docRoot}preview/download.html#docs">預覽版參考資料</a>。
+</p>
+
+<h3>重要行為變更</h3>
+
+<p>如果您先前曾發行過適用於 Android 的應用程式,請注意,您的應用程式會受到平台中的變更所影響。
+</p>
+
+<p>如需完整資訊,請參閱<a href="behavior-changes.html">行為變更</a>。</p>
+
+<h2 id="app-linking">應用程式連結</h2>
+<p>這個預覽版提供功能更強大的應用程式連結來增強 Android 的意圖系統。此功能讓您能夠將應用程式關聯到您自己的 Web 網域。
+根據這個關聯,平台可以判斷要用來處理特定 Web 連結的預設應用程式,並略過提示使用者選取應用程式的程序。如要深入瞭解如何實作此功能,請參閱<a href="{@docRoot}preview/features/app-linking.html">應用程式連結</a>。
+
+
+
+
+<h2 id="backup">針對應用程式進行自動備份</h2>
+<p>系統現在會針對應用程式執行自動完整資料備份與還原。預設會針對目標為 M 預覽版的應用程式啟用這個行為;您不需要新增任何其他的程式碼。
+如果使用者刪除他們的 Google 帳戶,也會同時刪除他們的備份資料。
+如要深入瞭解此功能的運作方式以及如何在檔案系統上設定要備份的內容,請參閱<a href="{@docRoot}preview/backup/index.html">針對應用程式進行自動備份</a>。
+
+</p>
+
+<h2 id="authentication">驗證</h2>
+<p>這個預覽版提供新的 API,讓您能夠在支援的裝置上利用使用者的指紋掃描來驗證他們,並使用裝置解鎖機制 (例如鎖定螢幕密碼) 來檢查距離最後一次驗證該使用者的時間有多接近。
+
+將這些 API 與 <a href="{@docRoot}training/articles/keystore.html">Android 金鑰存放區系統</a>搭配使用。
+</p>
+
+<h3 id="fingerprint-authentication">指紋驗證</h3>
+
+<p>如要透過指紋掃描驗證使用者,請取得新的
+{@code android.hardware.fingerprint.FingerprintManager} 類別的執行個體,然後呼叫
+{@code FingerprintManager.authenticate()} 方法。您的應用程式必須在配備指紋感應器的相容裝置上執行。
+您必須在應用程式上實作適用於指紋驗證流程的使用者介面,並在您的 UI 中使用標準的 Android 指紋圖示。Android 指紋圖示 ({@code c_fp_40px.png}) 隨附於<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">範例應用程式</a>中。如果您正在開發多個使用指紋驗證的應用程式,請注意,每個應用程式都必須個別驗證使用者的指紋。
+
+
+
+
+</p>
+
+<p>如要在您的應用程式中使用此功能,請先在您的宣示說明中新增 {@code USE_FINGERPRINT} 權限。
+</p>
+
+<pre>
+<uses-permission
+ android:name="android.permission.USE_FINGERPRINT" />
+</pre>
+
+<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+
+<p>如要查看指紋驗證的應用程式實作,請參閱<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">指紋對話方塊範例</a>。
+
+</p>
+
+<p>如果您正在測試此功能,請依照下列步驟執行:</p>
+<ol>
+<li>安裝 Android SDK 工具修訂版 24.3 (如果您尚未安裝)。</li>
+<li>前往 [設定] > [安全性] > [指紋]<strong></strong>,然後依照註冊指示,在模擬器中註冊新的指紋。
+</li>
+<li>使用模擬器,利用下列命令來模擬指紋輕觸事件。
+使用同一個命令,在鎖定螢幕上或您的應用程式中模擬指紋輕觸事件。
+
+<pre class="no-prettyprint">
+adb -e emu finger touch <finger_id>
+</pre>
+<p>在 Windows 上,您可能必須執行 {@code telnet 127.0.0.1 <emulator-id>},後面接著
+{@code finger touch <finger_id>}。
+</p>
+</li>
+</ol>
+
+<h3 id="confirm-credential">確認認證</h3>
+<p>您的應用程式可以根據使用者最近一次將裝置解鎖的時間有多接近來驗證他們。此功能讓使用者不需記住其他應用程式特定的密碼,並且讓您不需要實作自己的驗證使用者介面。
+
+您的應用程式應該將此功能與公用或秘密金鑰實作搭配使用,來進行使用者驗證。
+</p>
+
+<p>如要設定在成功驗證使用者之後,同一個金鑰可重複使用的逾時時間長度,可在您設定 {@link javax.crypto.KeyGenerator} 或
+{@link java.security.KeyPairGenerator} 時,呼叫新的
+{@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()}
+方法。
+此功能目前適用於對稱式密碼編譯操作。
+</p>
+
+<p>避免過度顯示重新驗證對話方塊 -- 您的應用程式應該先嘗試使用密碼編譯物件,如果逾時過期,才使用
+{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
+方法在您的應用程式內重新驗證使用者。
+
+</p>
+
+<p>如要查看此功能的應用程式實作,請參閱<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">確認認證範例</a>。
+
+</p>
+
+<h2 id="direct-share">直接分享</h2>
+
+<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
+
+<p>這個預覽版提供 API,讓使用者能夠以直覺且快速的方式進行分享。您現在可以定義「直接分享目標」<em></em>,在您的應用程式中啟動特定的行為。這些直接分享目標是透過 [分享]<em></em> 選單來向使用者公開。
+
+此功能讓使用者能夠將內容分享到其他應用程式內的目標,例如聯絡人。
+例如,直接分享目標可以在其他社交網路應用程式中啟動某個活動,讓使用者能夠在該應用程式中,直接與特定的朋友或社群分享內容。
+
+</p>
+
+<p>如要啟用直接分享目標,您必須定義一個類別來擴充
+{@code android.service.} <br>
+{@code chooser.ChooserTargetService} 類別。在宣示說明中宣告您的
+{@code ChooserTargetService}。在該宣告中,指定
+{@code BIND_CHOOSER_TARGET_SERVICE} 權限以及含有
+{@code SERVICE_INTERFACE} 動作的意圖篩選條件。</p>
+<p>下列範例示範如何在您的宣示說明中宣告 {@code ChooserTargetService}。
+</p>
+<pre>
+<service android:name=".ChooserTargetService"
+ android:label="@string/service_name"
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.chooser.ChooserTargetService" />
+ </intent-filter>
+</service>
+</pre>
+
+<p>針對您要向 {@code ChooserTargetService} 公開的每個活動,在您的應用程式宣示說明中,新增名稱為
+{@code "android.service.chooser.chooser_target_service"} 的
+{@code <meta-data>} 元素。
+</p>
+
+<pre>
+<activity android:name=".MyShareActivity”
+ android:label="@string/share_activity_label">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ </intent-filter>
+<meta-data
+ android:name="android.service.chooser.chooser_target_service"
+ android:value=".ChooserTargetService" />
+</activity>
+</pre>
+
+<h2 id="voice-interactions">語音互動</h2>
+<p>
+這個預覽版提供新的語音互動 API,可與<a href="https://developers.google.com/voice-actions/" class="external-link">語音操作</a>搭配使用,讓您能夠在應用程式內建置交談式語音體驗。
+
+呼叫
+{@code android.app.Activity.isVoiceInteraction()} 方法,來判斷是否已啟動您的活動來回應語音操作。
+如果是,則您的應用程式可以使用
+{@code android.app.VoiceInteractor} 類別,來要求使用者進行語音確認、從選項清單中選取,以及其他更多動作。
+如要深入瞭解如何實作語音操作,請參閱<a href="https://developers.google.com/voice-actions/interaction/" class="external-link">語音操作開發人員網站</a>。
+
+</p>
+
+<h2 id="assist">協助 API</h2>
+<p>
+這個預覽版提供一種新方式,可透過小幫手吸引使用者來使用您的應用程式。如要使用此功能,使用者必須啟用小幫手來使用目前的內容。
+啟用之後,使用者就能夠在所有應用程式內,按住 <strong>Home</strong> 按鈕不放來啟用小幫手。
+</p>
+<p>您的應用程式可以設定
+{@link android.view.WindowManager.LayoutParams#FLAG_SECURE} 旗標,選擇不要與小幫手分享目前的內容。除了平台傳遞給小幫手的一組標準資訊之外,您的應用程式也可以使用新的 {@code android.app.Activity.AssistContent} 類別來分享其他資訊。
+
+</p>
+
+<p>如要將您應用程式的其他內容提供給小幫手,請依照下列步驟執行:</p>
+
+<ol>
+<li>實作 {@link android.app.Application.OnProvideAssistDataListener} 介面。</li>
+<li>使用
+{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()} 來註冊這個監聽器。</li>
+<li>如要提供特定活動的內容資訊,請覆寫
+ {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
+回呼,然後選擇性地覆寫新的 {@code Activity.onProvideAssistContent()} 回呼。
+</ol>
+
+<h2 id="notifications">通知</h2>
+<p>這個預覽版新增了下列適用於通知的 API 變更:</p>
+<ul>
+ <li>新的 {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} 篩選條件級別,會對應至新的「僅允許鬧鐘」<em></em>的請勿打擾模式。
+</li>
+ <li>新的 {@code Notification.CATEGORY_REMINDER} 類別值,可用來分辨來自其他事件 ({@link android.app.Notification#CATEGORY_EVENT}) 與鬧鐘 ({@link android.app.Notification#CATEGORY_ALARM}) 的使用者排程提醒。
+
+
+</li>
+ <li>新的 {@code android.graphics.drawable.Icon} 類別,可以透過 {@code Notification.Builder.setSmallIcon(Icon)} 和
+{@code Notification.Builder.setLargeIcon(Icon)} 方法來附加您的通知。
+</li>
+ <li>新的 {@code NotificationManager.getActiveNotifications()} 方法,讓您的應用程式能夠找出它們目前有哪些通知仍處於有效狀態。
+如要查看使用此功能的應用程式實作,請參閱<a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">使用中通知範例</a>。
+</li>
+</ul>
+
+<h2 id="bluetooth-stylus">藍牙手寫筆支援</h2>
+<p>這個預覽版提供對於使用者使用藍牙手寫筆進行輸入的改良支援。使用者可以將相容的藍芽手寫筆與他們的手機或平板電腦配對並連線。
+連線之後,來自觸控螢幕的位置資訊會與來自手寫筆的壓力和按鈕資訊結合,比起單獨使用觸控螢幕,這樣能夠提供更大範圍的表達方式。
+
+您的應用程式可以藉由在您的活動中註冊新的
+{@code View.onStylusButtonPressListener} 和 {@code GestureDetector.OnStylusButtonPressListener}
+回呼,來監聽手寫筆按鈕的按下動作,並執行次要動作。
+</p>
+
+<p>使用 {@link android.view.MotionEvent} 方法和常數來偵測手寫筆按鈕互動:
+</p>
+<ul>
+<li>如果使用者使用具有一個按鈕的手寫筆輕觸應用程式的螢幕,則
+{@link android.view.MotionEvent#getToolType(int) getTooltype()} 方法會傳回
+{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}。</li>
+<li>針對目標為 M 預覽版的應用程式,
+{@link android.view.MotionEvent#getButtonState() getButtonState()}
+方法會在使用者按下主要手寫筆按鈕時傳回 {@code MotionEvent.STYLUS_BUTTON_PRIMARY}。
+如果手寫筆有第二個按鈕,則當使用者按下該按鈕時,同一個方法會傳回
+{@code MotionEvent.STYLUS_BUTTON_SECONDARY}。如果使用者同時按下這兩個按鈕,此方法即會使用 OR 連結,一併傳回這兩個值 ({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY})。
+
+</li>
+<li>
+針對目標為較低平台版本的應用程式,
+{@link android.view.MotionEvent#getButtonState() getButtonState()} 方法會傳回
+{@link android.view.MotionEvent#BUTTON_SECONDARY} (針對主要手寫筆按鈕的按下動作)、
+{@link android.view.MotionEvent#BUTTON_TERTIARY} (針對次要手寫筆按鈕的按下動作),或兩者。
+</li>
+</ul>
+
+<h2 id="ble-scanning">已改進藍牙低電量掃描</h2>
+<p>
+如果您的應用程式會執行藍芽低電量掃描,就可以使用新的
+{@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} 方法,來指定如果先找到符合
+{@link android.bluetooth.le.ScanFilter} 組合的廣告封包,以及在某個時段中找不到它時,只需通知回呼。
+
+比起先前平台版本中所提供的功能,這個掃描方法功能更強大且更有效率。
+
+</p>
+
+<h2 id="hotspot">無線基地台 2.0 版本 1 支援</h2>
+<p>
+這個預覽版在 Nexus 6 和 Nexus 9 裝置上新增對於無線基地台 2.0 版本 1 規格的支援。如要在您的應用程式中佈建無線基地台 2.0 認證,請使用
+{@link android.net.wifi.WifiEnterpriseConfig} 類別的新方法,例如 {@code setPlmn()} 和
+{@code setRealm()}。
+在 {@link android.net.wifi.WifiConfiguration} 物件中,您可以設定
+{@link android.net.wifi.WifiConfiguration#FQDN} 和 {@code providerFriendlyName} 欄位。新的 {@code ScanResult.PasspointNetwork} 屬性指出偵測到的網路是否代表無線基地台 2.0 存取點。
+
+
+</p>
+
+<h2 id="4K-display">4K 顯示模式</h2>
+<p>此平台現在允許應用程式能夠要求將在相容硬體中呈現的顯示解析度升級到 4K。
+如要查詢目前的實際解析度,請使用新的
+{@code android.view.Display.Mode} API。如果 UI 是使用較低的邏輯解析度來繪製,並向上升級為較高的實際解析度,請注意,
+{@code Display.Mode.getPhysicalWidth()} 方法傳回的實際解析度可能會與 {@link android.view.Display#getSize(android.graphics.Point) getSize()} 報告的邏輯解析度不同。
+
+</p>
+
+<p>您可以在應用程式執行時,藉由設定應用程式視窗的 {@code WindowManager.LayoutParams.preferredDisplayModeId} 屬性,來要求系統變更該應用程式中的實際解析度。
+如果您想要切換為 4K 顯示解析度,這個功能非常實用。
+儘管在 4K 顯示模式中,UI 會持續使用原始解析度 (例如 1080p) 來呈現並向上升級為 4K,但是
+{@link android.view.SurfaceView} 物件可能會以原生解析度來顯示內容。
+</p>
+
+<h2 id="behavior-themeable-colorstatelists">具備設計風格的 ColorStateList</h2>
+<p>針對執行 M 預覽版的裝置,
+{@link android.content.res.ColorStateList} 中目前支援設計風格屬性。
+{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} 和
+{@link android.content.res.Resources#getColor(int) getColor()} 方法已過時。如果您正在呼叫這些 API,請改為呼叫新的 {@code Context.getColorStateList()} 或
+{@code Context.getColor()} 方法。
+您也可以透過 {@link android.support.v4.content.ContextCompat},在 v4 appcompat 程式庫中取得這些方法。
+</p>
+
+<h2 id="audio">音訊功能</h2>
+
+<p>這個預覽版在 Android 上新增了音訊處理的增強功能,包括: </p>
+<ul>
+ <li>利用新的 {@code android.media.midi} API,來支援 <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> 通訊協定。
+使用這些 API 來傳送與接收 MIDI 事件。
+</li>
+ <li>新的 {@code android.media.AudioRecord.Builder} 和 {@code android.media.AudioTrack.Builder}
+類別,可分別建立數位音訊擷取和播放物件,並設定音訊來源和接收屬性來覆寫系統預設值。
+</li>
+ <li>API 勾點,適合用來關聯音訊與輸入裝置。如果您的應用程式允許使用者從連接到 Android TV 的遊戲控制器或遙控器啟動音訊搜尋,則這特別有用。系統會在使用者啟動搜尋時,叫用新的 {@code android.app.Activity.onSearchRequested()} 回呼。
+
+
+如要判斷使用者的輸入裝置是否有內建的麥克風,請從該回呼中擷取 {@link android.view.InputDevice} 物件,然後呼叫新的
+{@code InputDevice.hasMic()} 方法。
+</li>
+ <li>新的 {@code android.media.AudioDevicesManager} 類別,讓您能夠擷取所有已連接的來源與接收音訊裝置的清單。
+如果您想要讓應用程式在連接或中斷連接音訊裝置時收到通知,也可以指定
+{@code android.media.OnAudioDeviceConnectionListener} 物件。
+</li>
+</ul>
+
+<h2 id="video">影片功能</h2>
+<p>這個預覽版在影片處理 API 中增加了新功能,包括:</p>
+<ul>
+<li>新的 {@code android.media.MediaSync} 類別,可協助應用程式同步轉譯音訊和影片串流。
+音訊緩衝區是利用非封鎖的方式來提交,並透過回呼來傳回。
+它也支援動態播放速率。
+</li>
+<li>新的 {@code MediaDrm.EVENT_SESSION_RECLAIMED} 事件,指出應用程式開啟的工作階段已由資源管理員所回收。
+如果您的應用程式使用 DRM 工作階段,就應該處理這個事件,並確定不會使用回收的工作階段。
+
+</li>
+<li>新的 {@code MediaCodec.CodecException.ERROR_RECLAIMED} 錯誤碼,表示資源管理員已回收轉碼器所使用的媒體資源。
+如果發生這個例外狀況,就必須釋放轉碼器,就如同它已進入終止狀態。
+
+</li>
+<li>新的 {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} 介面,可取得支援並行轉碼器執行個體數目上限的提示。
+
+</li>
+<li>新的 {@code MediaPlayer.setPlaybackParams()} 方法,可將媒體播放速率設定為快速或慢速播放。
+這也可以和影片一起自動延伸或加速音訊播放。
+</li>
+</ul>
+
+<h2 id="camera">相機功能</h2>
+<p>這個預覽版包含下列可用來存取相機閃光燈和相機重新處理影像的 API:
+</p>
+
+<h3 id="flashlight">閃光燈 API</h3>
+<p>如果相機裝置具有閃光裝置,則您可以呼叫 {@code CameraManager.setTorchMode()}
+方法,在不開啟相機裝置的情況下,開啟或關閉閃光裝置的閃光模式。應用程式不具備閃光裝置或相機裝置的獨佔擁有權。
+每當相機裝置變成無法使用時,或者,當其他相機資源讓閃光變成無法使用時,閃光模式也會關閉且變成無法使用。
+
+其他應用程式也會呼叫 {@code setTorchMode()}
+來關閉閃光模式。關閉最後一個開啟閃光模式的應用程式時,閃光模式即會關閉。
+</p>
+
+<p>您可以呼叫
+{@code CameraManager.registerTorchCallback()} 方法,來註冊回呼要收到有關閃光模式狀態的通知。第一次註冊回呼時,會立即使用所有目前已知具有閃光裝置之相機裝置的閃光模式來呼叫它。
+
+如果成功開啟或關閉閃光模式,即會叫用
+{@code CameraManager.TorchCallback.onTorchModeChanged()} 方法。</p>
+
+<h3 id="reprocessing">重新處理 API</h3>
+<p>{@link android.hardware.camera2 Camera2} API 已擴充,支援重新處理 YUV 和私人不透明格式的影像。
+您的應用程式會判斷是否可透過 {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES} 使用重新處理功能。
+如果裝置支援重新處理,您就可以呼叫
+{@code CameraDevice.createReprocessableCaptureSession()} 來建立可重新處理的相機拍攝工作階段,然後建立適用於重新處理輸入緩衝區的要求。
+
+</p>
+
+<p>使用 {@code ImageWriter} 類別,將輸入緩衝區流程連接到相機重新處理輸入。
+如要取得空的緩衝區,請依照這個程式設計模型執行:</p>
+
+<ol>
+<li>呼叫 {@code ImageWriter.dequeueInputImage()} 方法。</li>
+<li>在輸入緩衝區中填入資料。</li>
+<li>呼叫 {@code ImageWriter.queueInputImage()} 方法,將緩衝區傳送到相機。</li>
+</ol>
+
+<p>如果您將 {@code ImageWriter} 物件和
+{@code android.graphics.ImageFormat.PRIVATE} 影像一起使用,您的應用程式就無法直接存取影像資料。
+請改為呼叫 {@code ImageWriter.queueInputImage()} 方法但不含任何緩衝區複本,直接將 {@code ImageFormat.PRIVATE} 影像傳遞到
+{@code ImageWriter}。
+</p>
+
+<p>{@code ImageReader} 類別現在支援 {@code android.graphics.ImageFormat.PRIVATE} 格式的影像串流。
+這個支援讓您的應用程式能夠保留
+{@code ImageReader} 輸出影像的循環影像佇列、選取一或多個影像,然後將它們傳送到
+{@code ImageWriter} 以進行相機重新處理。</p>
+
+<h2 id="afw">Android for Work 功能</h2>
+<p>這個預覽版包含下列適用於 Android for Work 功能的新 API:</p>
+<ul>
+ <li><strong>已增強適用於公司擁有、單一用途裝置的控制項:</strong>裝置擁有者現在可以控制下列設定,來改進公司擁有、單一用途 (COSU) 裝置的管理:
+
+
+ <ul>
+ <li>使用
+{@code DevicePolicyManager.setKeyguardEnabledState()} 方法來停用或重新啟用滑動解鎖。</li>
+ <li>使用
+{@code DevicePolicyManager.setStatusBarEnabledState()} 方法,來停用或重新啟用狀態列 (包括快速設定、通知,以及啟動 Google 即時資訊的導覽向上滑動手勢)。
+</li>
+ <li>使用 {@link android.os.UserManager} 常數
+{@code DISALLOW_SAFE_BOOT} 來停用或重新啟用安全開機。</li>
+ <li>使用
+ {@link android.provider.Settings.Global} 常數 {@code STAY_ON_WHILE_PLUGGED_IN},防止螢幕在使用者為裝置連接電源時關閉。</li>
+ </ul>
+ </li>
+ <li><strong>透過裝置擁有者自動安裝與解除安裝應用程式:</strong>裝置擁有者現在可以使用 {@link android.content.pm.PackageInstaller}
+API (與 Google Play for Work 無關) 自動安裝與解除安裝應用程式。
+您現在可以透過裝置擁有者佈建裝置,該裝置擁有者可在不與使用者互動的情況下擷取並安裝應用程式。
+如要在不啟用 Google 帳戶的情況下輕觸一次就能佈建 Kiosk 或其他這類裝置,這個功能非常有用。
+</li>
+<li><strong>自動存取企業憑證:</strong>當應用程式呼叫
+{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()} 時,在系統提示使用者選取憑證之前,設定檔或裝置擁有者現在會呼叫 {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()} 方法,為提出要求的應用程式自動提供別名。
+
+
+這個功能讓您能夠在不與使用者互動的情況下,為受管理的應用程式授與存取憑證的權限。
+</li>
+<li><strong>自動接受系統更新。</strong>藉由使用
+{@code DevicePolicyManager.setSystemUpdatePolicy()} 來設定系統更新原則,裝置擁有者現在可以自動接受系統更新 (例如,在 Kiosk 裝置的案例中),或者延後更新,並防止使用者進行更新,最多 30 天。
+
+因此,系統管理員可以設定必須取得更新的每日時間範圍 ,例如,在 Kiosk 裝置處於未使用狀態時。
+在系統更新可供使用時,系統就會檢查工作原則控制器應用程式是否已設定系統更新原則,並據以運作。
+
+
+</li>
+<li>
+<strong>委派的憑證安裝:</strong>設定檔或裝置擁有者現在可以授與第三方廠商的應用程式呼叫這些 {@link android.app.admin.DevicePolicyManager} 憑證管理 API 的能力:
+
+
+<ul>
+ <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
+getInstalledCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
+hasCaCertInstalled()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
+installCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
+uninstallCaCert()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
+uninstallAllUserCaCerts()}</li>
+ <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
+installKeyPair()}</li>
+</ul>
+</li>
+<li><strong>企業原廠重設保護:</strong>佈建裝置擁有者時,您現在可以藉由設定
+{@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} 套件組合,來設定參數以解除鎖定原廠重設保護 (FRP)。
+NFC 程式設計人員應用程式可以在已重設裝置來解除鎖定 FRP 並佈建裝置之後提供這些參數,而不需使用先前設定的 Google 帳戶。
+
+如果您並未修改這些參數,FRP 會就地保留,並防止裝置在沒有先前啟用的 Google 認證的情況下啟用。
+
+
+<p>此外,裝置擁有者可以在 Google Play 服務上設定應用程式限制,來指定可用來解除鎖定 FRP 的替代 Google 帳戶,以取代已在裝置上啟用的帳戶。
+</p>
+</li>
+<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
+<li><strong>資料使用量追蹤。</strong>設定檔或裝置擁有者現在可以使用新的
+{@code android.app.usage.NetworkStatsManager} 方法,針對可在 [設定] > [資料]<strong></strong> 使用量中看見的資料使用量統計資料進行查詢。
+系統會自動授與設定檔擁有者權限來查詢他們所管理之設定檔上的資料,在此同時,裝置擁有者會取得受管理的主要使用者之使用量資料的存取權限。
+
+</li>
+<li><strong>執行階段權限管理:</strong>
+<p>設定檔或裝置擁有者可以使用
+{@code DevicePolicyManager.setPermissionPolicy()},針對所有應用程式的所有執行階段要求設定權限原則,以提示使用者授與一般權限,或者以無訊息方式自動授與或拒絕該權限。
+
+如果設定了後項原則,使用者就無法在應用程式權限畫面的 [設定]<strong></strong> 中,修改設定檔或裝置擁有者所做的選項。
+
+</p></li>
+<li><strong>設定中的 VPN:</strong>VPN 應用程式現在可以在 [設定] > [更多] > [VPN]<strong></strong> 中看見。此外,伴隨 VPN 使用量出現的通知是該 VPN 設定方式的特定通知。
+
+
+針對設定檔擁有者,通知是專門用來通知是否已針對受管理的設定檔、個人設定檔或兩者設定了 VPN。
+針對裝置擁有者,通知是專門用來通知是否已針對整個裝置設定了 VPN。
+</li>
+<li><strong>工作狀態通知:</strong>每當來自受管理設定檔的應用程式在前景中有活動時,狀態列上就會出現公事包圖示。
+因此,如果直接將裝置解除鎖定至受管理設定檔中應用程式的活動,即會顯示一個快顯通知,通知使用者他們正處於工作設定檔內。
+
+
+</li>
+</ul>
+
+<p class="note">
+ 如需 M 開發人員預覽版中所有 API 變更的詳細檢視,請參閱 <a href="{@docRoot}preview/download.html">API 差異報告</a>。
+</p>
diff --git a/docs/html-intl/intl/zh-tw/preview/behavior-changes.jd b/docs/html-intl/intl/zh-tw/preview/behavior-changes.jd
new file mode 100644
index 0000000..405aea1
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/behavior-changes.jd
@@ -0,0 +1,402 @@
+page.title=行為變更
+page.keywords=預覽版,sdk,相容性
+sdk.platform.apiLevel=MNC
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>本文件內容</h2>
+
+<ol id="toc44" class="hide-nested">
+ <li><a href="#behavior-runtime-permissions">執行階段權限</a></li>
+ <li><a href="#behavior-power">省電最佳化</a>
+ <ol>
+ <li><a href="#behavior-doze">休眠</a></li>
+ <li><a href="#behavior-app-standby">應用程式待命</a></li>
+ </ol>
+ </li>
+ <li><a href="#behavior-adoptable-storage">可採用的儲存裝置</a></li>
+ <li><a href="#behavior-apache-http-client">移除 Apache HTTP 用戶端</a></li>
+ <li><a href="#behavior-audiomanager-Changes">AudioManager 變更</a></li>
+ <li><a href="#behavior-test-selection">文字選取</a></li>
+ <li><a href="#behavior-keystore">Android 金鑰存放區變更</a></li>
+ <li><a href="#behavior-network">Wi-Fi 和網路變更</a></li>
+ <li><a href="#behavior-camera">相機服務變更</a></li>
+ <li><a href="#behavior-art-runtime">ART 執行階段</a></li>
+ <li><a href="#behavior-apk-validation">APK 驗證</a></li>
+ <li><a href="#behavior-afw">Android for Work 變更</a></li>
+</ol>
+
+<h2>API 差異</h2>
+<ol>
+<li><a href="{@docRoot}preview/download.html">API 級別 22 到 M 預覽版»</a> </li>
+</ol>
+
+
+<h2>另請參閱</h2>
+<ol>
+<li><a href="{@docRoot}preview/api-overview.html">M 開發人員預覽版 API 總覽</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p>除了新特性和功能以外,M 開發人員預覽版還包含各種不同的系統變更和 API 行為變更。
+本文件將強調說明一些您應該知道且在您的應用程式中加以考量的重要變更。
+</p>
+
+<p>如果您先前曾發行過適用於 Android 的應用程式,請注意,您的應用程式可能會受到平台中的這類變更所影響。
+</p>
+
+<h2 id="behavior-runtime-permissions">執行階段權限</h1>
+<p>這個預覽版引進了新的權限模型,使用者現在可以在執行階段直接管理應用程式權限。
+這個模型為使用者提供了改良的能見度並使其可完全控制權限,同時為應用程式開發人員提供更流暢的安裝和自動更新程序。使用者可以針對安裝的應用程式個別授與或撤銷權限。
+
+ </p>
+
+<p>在目標為 M 預覽版的應用程式中,請務必在執行階段檢查並要求權限。
+如要判斷您的應用程式是否已獲授與權限,請呼叫新的 {@code Context.checkSelfPermission()} 方法。
+如要要求權限,請呼叫新的
+{@code Activity.requestPermission()} 方法。即使您的應用程式目標不是 M,還是應該在新的權限模型下測試您的應用程式。
+</p>
+
+<p>如需在您的應用程式中支援新權限模型的詳細資訊,請參閱<a href="{@docRoot}preview/features/runtime-permissions.html">權限</a>開發人員預覽版頁面。
+
+如需評估對您應用程式的影響的祕訣,請參閱<a href="{@docRoot}preview/testing/guide.html#runtime-permissions">測試指南</a>。
+</p>
+
+<h2 id="behavior-power">省電最佳化</h2>
+<p>這個預覽版針對閒置的裝置和應用程式引進了新的省電最佳化功能。</p>
+
+<h3 id="behavior-doze">休眠</h3>
+<p>如果拔除裝置電源並關閉螢幕使其保持靜止狀態一段時間,該裝置即會進入「休眠」<em></em>模式,它會嘗試讓系統保持睡眠狀態。
+在此模式中,裝置會在短期間內定期繼續執行正常操作,因此,會進行應用程式同步處理,而系統可以執行任何待處理的操作。
+
+</p>
+
+<p>處於休眠狀態時,下列限制會套用到您的應用程式:</p>
+<ul>
+<li>除非您的應用程式接收到高優先順序的 Google 雲端通訊活動訊號 (Tickle),否則會停用網路存取。
+</li>
+<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">喚醒鎖定</a>會被忽略。</li>
+<li>使用 {@link android.app.AlarmManager} 類別排定的鬧鐘會被停用,但使用 {@link android.app.AlarmManager#setAlarmClock setAlarmClock()}方法和 {@code AlarmManager.setAndAllowWhileIdle()} 設定的鬧鐘則不會被停用。
+
+</li>
+<li>WiFi 掃描不會執行。</li>
+<li>不容許執行您同步配接器的同步處理和工作以及 {@link android.app.job.JobScheduler}。
+</li>
+</ul>
+</p>
+<p>當裝置離開休眠狀態時,就會執行所有待處理的工作和同步處理。</p>
+<p>您可以測試此功能,方法是將執行 M 預覽版的裝置連接到您的開發電腦並呼叫下列命令:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell dumpsys deviceidle step
+$ adb shell dumpsys deviceidle -h
+</pre>
+<p class="note"><strong>注意:</strong>即將發行的 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google 雲端通訊</a>版本讓您能夠指定高優先順序的訊息。
+
+
+如果您的應用程式收到高優先順序的 GCM 訊息,即使裝置處於休眠狀態,系統還是會授與它短暫的網路存取權限。
+
+</p>
+
+<p>如需如何在您的應用程式中測試休眠的祕訣,請參閱<a href="{@docRoot}preview/testing/guide.html#doze-standby">測試指南</a>。
+
+ </p>
+
+<h3 id="behavior-app-standby">應用程式待命</h3>
+<p>使用這個預覽版時,系統可在應用程式處於未使用狀態時,判斷它們是否處於閒置狀態。
+除非系統偵測到以下任一個訊號,否則會在一段時間之後將應用程式視為閒置:
+</p>
+
+<ul>
+<li>使用者明確啟動應用程式。</li>
+<li>應用程式目前在前景中有一個處理程序 (可能是做為活動或前景服務,也可能正由其他活動或前景服務所使用)。
+</li>
+<li>應用程式產生使用者可以在鎖定螢幕或通知匣中看見的通知。
+</li>
+<li>使用者透過 [設定]<strong></strong> 明確要求應用程式不需進行最佳化。
+</li>
+</ul>
+
+<p>如果拔除了裝置電源,即會停用被視為閒置之應用程式的網路存取,並擱置它們的同步處理和工作。
+為裝置插上電源時,就允許這些應用程式進行網路存取,且可執行所有已擱置的工作和同步處理。
+如果裝置長時間處於閒置狀態,則允許閒置的應用程式進行網路存取,大約是一天一次。
+</p>
+
+<p>您可以測試此功能,方法是將執行 M 預覽版的裝置連接到您的開發電腦並呼叫下列命令:
+
+</p>
+<pre class="no-prettyprint">
+$ adb shell dumpsys battery unplug
+$ adb shell am set-idle <packageName> true
+$ adb shell am set-idle <packageName> false
+$ adb shell am get-idle <packageName>
+</pre>
+
+<p class="note"><strong>注意:</strong>即將發行的 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google 雲端通訊</a> (GCM) 版本讓您能夠指定高優先順序的訊息。
+
+
+如果您的應用程式收到高優先順序的 GCM 訊息,即使應用程式處於閒置狀態,系統還是會授與它短暫的網路存取權限。
+
+</p>
+
+<p>如需如何在您的應用程式中測試應用程式待命的祕訣,請參閱<a href="{@docRoot}preview/testing/guide.html#doze-standby">測試指南</a>。
+
+ </p>
+
+<h2 id="behavior-adoptable-storage">可採用的儲存裝置</h2>
+<p>
+使用這個預覽版時,使用者可以採用<em></em>像是 SD 卡的外部儲存裝置。採用外部儲存裝置會加密並格式化裝置,使其可如內部儲存空間般運作。
+此功能讓使用者能夠在儲存裝置之間移動應用程式和這些應用程式的私人資料。
+移動應用程式時,系統會採用宣示說明中的 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> 偏好設定。
+
+
+</p>
+
+<p>如果您的應用程式會存取下列 API 或欄位,請注意,在內部和外部儲存裝置之間移動應用程式時,它們傳回的檔案路徑將會動態變更。建置檔案路徑時,強烈建議您一律動態呼叫這些 API。請勿使用硬式編碼的檔案路徑或保留先前建置的完整檔案路徑。
+
+
+</p>
+
+<ul>
+<li>{@link android.content.Context} 方法:
+ <ul>
+ <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
+ <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
+ <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
+ <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
+ <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
+ <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
+ <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
+ <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
+ <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
+ </ul>
+</li>
+<li>{@link android.content.pm.ApplicationInfo} 欄位:
+ <ul>
+ <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
+ <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
+ </ul>
+</li>
+</ul>
+
+<p>如要在開發人員預覽版中對此功能進行偵錯,您可以執行下列命令來採用 USB 磁碟機 (這個磁碟機是透過 USB On-The-Go (OTG) 纜線連接到 Android 裝置):
+</p>
+
+<pre class="no-prettyprint">
+$ adb shell sm set-force-adoptable true
+</pre>
+
+<h2 id="behavior-apache-http-client">移除 Apache HTTP 用戶端</h2>
+<p>這個預覽版已移除對於 Apache HTTP 用戶端的支援。如果您的應用程式正在使用這個用戶端且目標為 Android 2.3 (API 級別 9) 或更高版本,請改為使用 {@link java.net.HttpURLConnection} 類別。
+
+這個 API 的效率更高,因為它能透過透明的壓縮和回應快取來降低網路使用量,並將電源耗用量降至最低。
+如要繼續使用 Apache HTTP API,您必須先在 {@code build.gradle} 檔案中宣告下列編譯時期的相依性:
+
+</p>
+<pre>
+android {
+ useLibrary 'org.apache.http.legacy'
+}
+</pre>
+<p>Android 正從 OpenSSL 移至 <a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> 程式庫。
+
+如果您正在應用程式中使用 Android NDK,請勿連結不屬於 NDK API 一部分的密碼編譯程式庫,例如 {@code libcrypto.so} 和 {@code libssl.so}。
+這些程式庫不是公用 API,而且可能在沒有通知的情況下,在新的版本和裝置上變更或終止支援。此外,您可能會讓自己暴露於安全性弱點中。
+
+因此,請改為修改您的原生程式碼,透過 JNI 來呼叫 Java 密碼編譯 API,或以靜態方式連結您選擇的密碼編譯程式庫。
+
+</p>
+
+<h2 id="behavior-audiomanager-Changes">AudioManager 變更</h2>
+<p>不再支援透過 {@link android.media.AudioManager} 類別直接設定音量或將特定串流設定為靜音。
+{@link android.media.AudioManager#setStreamSolo(int,boolean)
+setStreamSolo()} 方法已過時,您應該改為呼叫
+{@code AudioManager.requestAudioFocus()} 方法。同樣地,
+{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} 方法已過時;請改為呼叫 {@code AudioManager.adjustStreamVolume()} 方法並傳入方向值 {@code ADJUST_MUTE} 或 {@code ADJUST_UNMUTE}。
+
+</p>
+
+<h2 id="behavior-test-selection">文字選取</h2>
+
+<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
+
+<p>當使用者在您的應用程式中選取文字時,您現在可以在<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">浮動工具列</a>中顯示文字選取動作,例如,剪下<em></em>、複製<em></em>及貼上<em></em>。
+
+使用者互動實作類似於針對內容關聯動作列所做的實作,如<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">為個別的檢視啟用內容關聯動作模式</a>中所述。
+
+
+</p>
+
+<p>如要實作適用於文字選取的浮動工具列,請在您現有的應用程式中進行下列變更:
+</p>
+<ol>
+<li>在您的 {@link android.view.View} 或 {@link android.app.Activity} 物件中,將
+{@link android.view.ActionMode} 呼叫從
+{@code startActionMode(Callback)} 變更為 {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}。</li>
+<li>進行 {@code ActionMode.Callback} 的現有實作,並改為讓它擴充
+{@code ActionMode.Callback2}。</li>
+<li>覆寫 {@code Callback2.onGetContentRect()} 方法,以在檢視中提供內容 {@link android.graphics.Rect} 物件 (例如,文字選取矩形區塊) 的座標。
+</li>
+<li>如果矩形區塊位置不再有效,而且這是唯一變成無效的元素,請呼叫 {@code ActionMode.invalidateContentRect()} 方法。
+</li>
+</ol>
+
+<p>如果您正在使用 <a href="{@docRoot}tools/support-library/index.html">Android 支援程式庫</a>版本 22.2,請注意,浮動工具列無法向下相容,而且 appcompat 預設會取得 {@link android.view.ActionMode} 物件的完整控制權。
+
+
+這可防止浮動工具列顯示。如要在
+{@link android.support.v7.app.AppCompatActivity} 中啟用
+{@link android.view.ActionMode} 支援,請呼叫
+{@code android.support.v7.app.AppCompatActivity.getDelegate()},然後在傳回的
+{@link android.support.v7.app.AppCompatDelegate} 物件中呼叫
+{@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()},並將輸入參數設定為 {@code false}。
+這個呼叫會將 {@link android.view.ActionMode} 物件的控制權傳回架構中。
+儘管在 M 預覽版之前的裝置中,只支援 {@link android.support.v7.app.ActionBar} 模式,但在執行 M 預覽版的裝置中,允許架構支援
+{@link android.support.v7.app.ActionBar} 或浮動工具列模式。
+</p>
+
+<h2 id="behavior-keystore">Android 金鑰存放區變更</h2>
+<p>使用這個預覽版時,<a href="{@docRoot}training/articles/keystore.html">Android 金鑰存放區供應程式</a>不再支援 DSA。
+
+但仍支援 ECDSA。</p>
+
+<p>在停用或重設安全鎖定螢幕時 (例如,由使用者或裝置管理員執行),將不再刪除其餘不需加密的金鑰。
+在這些事件期間,將會刪除其餘需要加密的金鑰。
+</p>
+
+<h2 id="behavior-network">Wi-Fi 和網路變更</h2>
+
+<p>這個預覽版引進了下列對於 Wi-Fi 和網路 API 的行為變更。</p>
+<ul>
+<li>唯有當您建立了 {@link android.net.wifi.WifiConfiguration} 物件時,您的應用程式現在才能變更這些物件的狀態。
+系統不容許您修改或刪除由使用者或其他應用程式所建立的
+{@link android.net.wifi.WifiConfiguration} 物件。
+</li>
+<li>
+在以前,如果應用程式使用
+{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} 搭配
+{@code disableAllOthers=true} 設定來強制裝置連接到特定的 Wi-Fi 網路,裝置即會中斷與其他網路的連線,例如行動數據。
+在這個預覽版中,裝置不再中斷與這類其他網路的連線。如果您應用程式的 {@code targetSdkVersion} 是 {@code “20”} 或更低版本,即會將它固定到選取的 Wi-Fi 網路。
+
+如果您應用程式的 {@code targetSdkVersion} 是 {@code “21”} 或更高版本,請使用多網路 API (例如,
+{@link android.net.Network#openConnection(java.net.URL) openConnection()}、
+{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} 及新的
+{@code ConnectivityManager.bindProcessToNetwork()} 方法),以確保會在選取的網路上傳送它的網路流量。
+
+</li>
+</ul>
+
+<h2 id="behavior-camera">相機服務變更</h2>
+<p>在這個預覽版中,在相機服務中存取分享資源的模型已經從先前的「先進先服務」存取模型變更為依照優先順序針對處理程序進行處理的存取模型。
+
+對於服務行為的變更如下:</p>
+<ul>
+<li>存取相機子系統資源 (包括開啟和設定相機裝置) 的權限是根據用戶端應用程式處理程序的「優先順序」來授與。
+通常會為具有使用者可看見或前景活動的應用程式處理程序提供較高的優先順序,讓相機資源的取得和使用更可靠。
+
+</li>
+<li>優先順序較低之應用程式的使用中相機用戶端可能會在優先順序較高的應用程式嘗試使用相機時被系統「撤出」。
+在已過時的 {@link android.hardware.Camera} API 中,這會導致針對被撤出的用戶端呼叫
+{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}。
+
+在 {@link android.hardware.camera2 Camera2} API 中,會導致針對被撤出的用戶端呼叫
+{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
+。</li>
+<li>在配備適當相機硬體的裝置上,個別的應用程式處理程序能夠單獨開啟,同時使用不同的相機裝置。
+但是,相機服務現在可以偵測到且不允許多處理程序使用案例,同時存取會對任何已開啟的相機裝置造成顯著的效能或功能降級。
+
+此變更可能會導致優先順序較低的用戶端被「撤出」,即使沒有任何其他應用程式正直接嘗試存取同一個相機裝置也一樣。
+
+
+</li>
+<li>
+變更目前的使用者會導致先前的使用者帳戶所擁有之應用程式的使用中相機用戶端被撤出。
+相機的存取權受限於目前裝置使用者所擁有的使用者設定檔。例如,這實際上表示「訪客」帳戶在使用者切換到不同帳戶之後,將無法保留使用相機子系統的執行中處理程序。
+
+
+</li>
+</ul>
+
+<h2 id="behavior-art-runtime">ART 執行階段</h2>
+<p>ART 執行階段現在可以正確實作
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 方法的存取規則。這個變更會修正 Dalvik 在先前版本中以不正確方式檢查存取規則的問題。如果您的應用程式使用
+{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 方法且您想要覆寫存取檢查,請搭配已設定為 {@code true} 的輸入參數呼叫
+{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} 方法。
+
+
+
+如果您的應用程式使用 <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat 程式庫</a>或 <a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview 程式庫</a>,您就必須更新應用程式來使用這些程式庫的最新版本。
+
+
+否則,請確定從 XML 參考的所有自訂類別都會更新,如此一來就能存取其類別建構函式。
+</p>
+
+<p>這個預覽版會更新動態連結器的行為。動態連結器現在瞭解程式庫的 {@code soname} 與其路徑 (<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">公開的 Bug 6670</a>) 之間的差異,而且現在會實作依 {@code soname} 進行搜尋。
+
+
+
+先前可運作但含有錯誤 {@code DT_NEEDED} 項目 (通常是組建電腦之檔案系統上的絕對路徑) 的應用程式可能會在載入時失敗。
+</p>
+
+<p>{@code dlopen(3) RTLD_LOCAL} 旗標現在會以正確的方式實作。請注意,
+{@code RTLD_LOCAL} 是預設值,因此,對 {@code dlopen(3)} 的呼叫 (不會明確使用
+{@code RTLD_LOCAL}) 將會受到影響 (除非您的應用程式明確使用 {@code RTLD_GLOBAL})。使用
+{@code RTLD_LOCAL},由後續呼叫
+{@code dlopen(3)} (相對於 {@code DT_NEEDED} 項目所參考) 所載入的程式庫將無法使用符號。</p>
+</p>
+
+<h2 id="behavior-apk-validation">APK 驗證</h2>
+<p>此平台現在會執行較嚴格的 APK 驗證。如果檔案宣告於宣示說明中但未出現在 APK 本身中,則 APK 會被視為毀損。
+如果移除了任何內容,就必須重新簽署 APK。
+</p>
+
+<h2 id="behavior-afw">Android for Work 變更</h2>
+<p>這個預覽版包含下列對於 Android for Work 的行為變更:</p>
+<ul>
+<li><strong>個人內容中的工作聯絡人。</strong>Google 撥號程式通話記錄現在會在使用者檢視過去的通話記錄時顯示工作聯絡人。將 {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()} 設定為 {@code true},可以在 Google 撥號程式通話記錄中隱藏工作設定檔聯絡人。
+
+
+只有在您將 {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} 設定為 {@code false} 時,工作聯絡人才會透過藍牙,與個人聯絡人一起顯示於裝置上。
+
+預設會設定為 {@code true}。
+
+</li>
+<li><strong>移除 WiFi 設定:</strong>如果將工作設定檔刪除,則現在會移除由設定檔擁有者所新增的 WiFi 設定 (例如,透過呼叫
+{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
+addNetwork()} 方法)。
+</li>
+<li><strong>鎖定 WiFi 設定:</strong>使用者無法再修改或刪除任何由使用中裝置擁有者所建立的 WiFi 設定。
+只要尚未針對使用者設定 {@link android.os.UserManager} 常數
+{@link android.os.UserManager#DISALLOW_CONFIG_WIFI},該使用者就仍能建立和修改他們自己的 WiFi 設定。
+</li>
+<li><strong>透過 Google 帳戶新增來下載工作原則控制器:</strong>在將要求透過工作原則控制器 (WPC) 應用程式進行管理的 Google 帳戶新增到受管理內容以外的裝置時,新增帳戶流程現在會提示使用者安裝適當的 WPC。這個行為也適用於在初始裝置設定精靈中透過 [設定] > [帳戶]<strong></strong> 來新增的帳戶。
+
+
+
+</li>
+<li><strong>對於特定 DevicePolicyManager API 行為的變更:</strong>呼叫 {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
+方法,只會對正在呼叫之使用者的相機產生影響;從受管理的設定檔呼叫它則不會對在主要使用者上執行的相機應用程式產生影響。
+
+此外,除了裝置擁有者,
+{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
+方法現在還可供設定檔擁有者使用。設定檔擁有者可以設定下列滑動解鎖限制:
+
+<ul>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} 和
+{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT},它們會對設定檔上層使用者的滑動解鎖設定產生影響。
+</li>
+<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS},這只會影響受管理設定檔中由應用程式所產生的通知。
+</li>
+</ul>
+</li>
+</ul>
diff --git a/docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd b/docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd
new file mode 100644
index 0000000..cf756aa
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/features/runtime-permissions.jd
@@ -0,0 +1,794 @@
+page.title=權限
+page.tags=previewresources, androidm
+page.keywords=權限, 執行階段, 預覽
+page.image={@docRoot}preview/features/images/permissions_check.png
+@jd:body
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>快速檢視</h2>
+ <ul>
+ <li>如果您的應用程式是以 M 預覽版 SDK 為目標,它會提示使用者在執行階段授與權限,而不是安裝期間。
+</li>
+ <li>使用者能隨時從應用程式 [設定] 畫面撤銷權限。
+</li>
+ <li>您的應用程式每次執行時都需要檢查它是否有所需的權限。
+</li>
+ </ul>
+
+ <h2>本文件內容</h2>
+ <ol>
+ <li><a href="#overview">總覽</a></li>
+ <li><a href="#coding">編寫執行階段權限的程式碼</a></li>
+ <li><a href="#testing">測試執行階段權限</a></li>
+ <li><a href="#best-practices">建議做法</a></li>
+ </ol>
+
+<!--
+ <h2>Related Samples</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+
+<!--
+ <h2>See also</h2>
+ <ol>
+ <li></li>
+ </ol>
+-->
+ </div> <!-- qv -->
+</div> <!-- qv-wrapper -->
+
+
+<p>
+ M 開發人員預覽版導入新的應用程式權限模型,簡化使用者安裝和升級應用程式的程序。
+如果 M 預覽版上執行的應用程式支援新的權限模型,使用者安裝或升級應用程式時,不需要授與任何權限。應用程式會在需要時才要求權限,而且系統會對使用者顯示要求權限的對話方塊。
+
+
+
+
+</p>
+
+<p>
+ 如果應用程式支援新的權限模型,它仍能在在執行舊版 Android 的裝置上安裝並執行 (在那些裝置上使用舊的權限模型)。
+
+
+</p>
+
+<h2 id="overview">
+ 總覽
+</h2>
+
+<p>
+ 使用 M 開發人員預覽版,平台導入新的應用程式權限模型。
+以下是這個新模型的主要元件摘要:
+</p>
+
+<ul>
+ <li>
+ <strong>宣告權限:</strong>應用程式會在宣示說明中宣告所需的所有權限,如舊版 Android 平台。
+
+ </li>
+
+ <li>
+ <strong>權限群組:</strong>權限會根據其功能分為「權限群組」
+<em></em>。例如,
+<code>CONTACTS</code> 權限群組包含讀取和寫入使用者聯絡人與設定檔資訊的權限。
+
+ </li>
+
+ <li>
+ <p><strong>安裝期間授與的有限權限:</strong>當使用者安裝或更新應用程式時,系統會將應用程式所要求且歸入 {@link
+android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} 的所有權限授與應用程式。
+
+
+ 例如,會在安裝期間自動授與歸入 {@link
+android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} 的鬧鐘與網際網路權限。
+
+ </p>
+
+ <p>系統也會授與應用程式簽名和系統權限,如<a href="#system-apps">系統應用程式和簽名</a>所述。
+
+安裝期間「不」<em></em>會提示使用者授與任何權限。
+</p>
+ </li>
+
+ <li>
+ <strong>使用者在執行階段授與權限:</strong>應用程式要求權限時,系統會對使用者顯示對話方塊,接著呼叫應用程式的回呼函數,通知它是否已授與權限。
+
+如果使用者授與權限,應用程式會獲得在應用程式宣示說明中所宣告之權限功能區域中的所有權限。
+
+
+ </li>
+
+</ul>
+
+<p>
+ 此權限模型改變應用程式要求權限的功能行為。
+以下是您應遵循以調整此模型的開發做法摘要:
+
+</p>
+
+<ul>
+
+ <li>
+ <strong>一律檢查是否具備權限:</strong>當應用程式需要執行任何需要權限的動作時,都應要先檢查是否具備有該權限。
+
+若不具備,即要求獲得授與該權限。
+
+ </li>
+
+ <li>
+ <strong>適當處理缺少權限的情況:</strong>如果應用程式未獲授與適當的權限,它應要能完全處理失敗。
+
+ 例如,若只有新增功能需要該權限,應用程式可以將該功能停用。
+如果應用程式務必要具備該權限才能運作,應用程式可以停用其所有功能,並通知使用者務必要授與該權限。
+
+
+ </li>
+
+ <div class="figure" style="width:220px" id="fig-perms-screen">
+ <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
+ <p class="img-caption">
+ <strong>圖 1.</strong>應用程式 [設定] 的權限畫面。
+ </p>
+ </div>
+
+ <li>
+ <strong>權限可以撤銷:</strong>使用者可以隨時撤銷應用程式的權限。
+如果使用者關閉應用程式的權限,並「不」<em></em>會通知應用程式。
+再次強調,您的應用程式在執行任何受限制的動作之前,應該驗證它是否具備所需的權限。
+
+ </li>
+</ul>
+
+<p class="note">
+ <strong>注意:</strong>如果應用程式是以 M 開發人員預覽版為目標,「務必要」
+<em></em>使用新的權限模型。
+</p>
+
+<p>
+ 自 M 開發人員預覽版推出起,並非所有 Google 應用程式都完全實作新的權限模型。
+Google 正透過 M 開發人員預覽版逐漸更新這些應用程式,以適當保留權限切換設定。
+
+
+</p>
+
+<p class="note">
+ <strong>注意:</strong>如果您的應用程式有自己的 API 介面,務必要先確定呼叫端具備存取該資料的必要權限後,再 Proxy 權限。
+
+
+</p>
+
+<h3 id="system-apps">
+ 系統應用程式和簽名權限
+</h3>
+
+<p>
+ 一般來說,當使用者安裝應用程式時,系統只會將
+ {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL
+ PROTECTION_NORMAL} 授與應用程式。不過,在某些情況下,系統會授與應用程式更多權限:
+
+</p>
+
+<ul>
+ <li>如果應用程式屬於系統映像的一部分,會自動獲授與其宣示說明中列出的所有權限。
+
+ </li>
+
+ <li>如果應用程式要求宣示說明中歸入 {@link
+android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} 的權限,並和宣告那些權限的應用程式一樣,以相同的憑證簽署應用程式,系統會在安裝時將那些權限授與要求的應用程式。
+
+
+
+ </li>
+</ul>
+
+<p>
+ 在這兩種情況下,使用者仍能隨時撤銷權限,只要前往系統的 [設定]<strong></strong> 畫面,然後選擇 [應用程式] ><strong></strong>
+
+ <i>app_name</i> > [權限]<strong></strong>。應用程式應持續在執行階段檢查是否具備權限,並在必要時予以要求。
+
+
+</p>
+
+<h3 id="compatibility">
+ 往後和回溯相容性
+</h3>
+
+<p>
+ 如果應用程式不是以 M 開發人員預覽版為目標,即使在 M 預覽版裝置上,應用程式也會持續使用舊的權限模型。
+當使用者安裝應用程式時,系統會要求使用者授與應用程式的宣示說明中列出的所有權現。
+
+
+</p>
+
+<p class="note">
+ <strong>注意:</strong>在執行 M 開發人員預覽版的裝置上,使用者能從應用程式的設定畫面關閉任何應用程式 (包括舊版應用程式) 的權限。
+
+如果使用者關閉舊版應用程式的權限,系統會自動停用適當功能。
+當應用程式嘗試執行需要那項權限的操作時,該操作不一定會造成例外狀況。
+
+而可能傳回空的資料集,通知發生錯誤,或展示未預期的行為。
+例如,如果您不具備查詢行事曆的權限,方法會傳回空的資料集。
+
+</p>
+
+<p>
+ 如果您在並非執行 M 預覽版的裝置上使用新的權限模型來安裝應用程式,系統會將它和任何其他應用程式一視同仁:系統會在安裝期間要求使用者授與所有宣告的權限。
+
+
+
+</p>
+
+<p class="note">
+ <strong>注意:</strong>對於預覽版,您必須將 SDK 最低版本設定為 M 預覽版 SDK,才能以預覽版 SDK 編譯。
+這表示在開發人員預覽版期間,您將無法在舊版平台上測試這類應用程式。
+
+
+</p>
+
+<h3 id="perms-vs-intents">權限與意圖比較</h3>
+
+<p>
+ 在許多情況下,您可以為應用程式在兩種方法當中擇一來執行工作。
+您可以讓應用程式要求權限以自行執行操作。
+或者,您可以讓應用程式使用意圖,讓其他應用程式來執行工作。
+
+</p>
+
+<p>
+ 例如,假設您的應用程式需要能夠使用裝置相機拍攝相片。
+您的應用程式能要求
+<code>android.permission.CAMERA</code> 權限,讓應用程式直接存取相機。
+接著,應用程式會使用相機 API 來控制相機並拍攝相片。
+這種方法可讓您的應用程式對攝影處理程序有完整控制權,並讓您將相機 UI 納入應用程式。
+
+
+</p>
+
+<p>
+ 不過,如果您不需要這類控制權,您可以只使用 {@link
+android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} 意圖來要求影像。
+當您啟動意圖時,會提示使用者選擇相機應用程式 (如果還沒有預設的相機應用程式),然後該應用程式會拍攝相片。
+
+相機應用程式會將相片傳回應用程式的 {@link
+ android.app.Activity#onActivityResult onActivityResult()} 方法。
+</p>
+
+<p>
+ 同樣地,如果您需要撥打電話、存取使用者的聯絡人等等,您都可以建立適當的意圖來執行,或是要求權限,然後直接存取適當的物件。
+
+每種方法各有利弊。
+
+</p>
+
+<p>
+ 如果您使用權限:
+</p>
+
+<ul>
+ <li>當您執行操作時,應用程式對使用者體驗有完整控制權。
+不過,如此多樣化控制使您必須設計適當的 UI,而增加工作複雜度。
+
+ </li>
+
+ <li>當您初次執行操作時,會提示使用者授與權限 (僅此一次)。
+之後應用程式可以逕行執行該操作,不需要再與使用者有其他互動。
+不過,如果使用者未授與權限 (或稍後予以撤銷),您的應用程式會完全無法執行該操作。
+
+
+ </li>
+</ul>
+
+<p>
+ 如果您使用意圖:
+</p>
+
+<ul>
+ <li>您不必為該操作設計 UI。處理意圖的應用程式會提供 UI。不過,這表示您對使用者體驗沒有控制權。
+
+使用者可能會和您不曾見過的應用程式互動。
+
+ </li>
+
+ <li>如果使用者沒有執行該操作的預設應用程式,系統會提示使用者選擇應用程式。如果使用者未指定預設處理常式,每次執行操作時可能都要完成額外的對話方塊。
+
+
+
+ </li>
+</ul>
+
+<h2 id="coding">編寫執行階段權限的程式碼</h2>
+
+<p>
+ 如果您的應用程式是以新的 M 開發人員預覽版為目標,請務必使用新的權限模型。
+這表示除了在宣示說明中宣告所需的權限之外,您也必須在執行階段檢查是否具備權限,並在您不具備時要求權限。
+
+
+
+</p>
+
+<h3 id="enabling">
+ 啟用新的權限模型
+</h3>
+
+<p>
+ 如要啟用新的 M 開發人員預覽版權限模型,可將應用程式的
+<code>targetSdkVersion</code> 屬性設定為 <code>"MNC"</code>,並將
+<code>compileSdkVersion</code> 設定為 <code>"android-MNC"</code>。這樣做可啟用所有新權限功能。
+
+</p>
+
+<p>
+ 對於預覽版,您必須將 <code>minSdkVersion</code> 設定為
+<code>"MNC"</code>,才能以預覽版 SDK 編譯。
+</p>
+
+<h3 id="m-only-perm">
+ 指定只限 M 預覽版使用的權限
+</h3>
+
+<p>
+ 您可以在宣示說明中使用新的 <code><uses-permission-sdk-m></code> 元素,指出只有在 M 預覽版上才需要某權限。
+如果您以這種方式宣告權限,每當在舊版裝置上安裝應用程式時,系統都不會提示使用者或將權限授與應用程式。藉由使用 <code><uses-permission-sdk-m></code> 元素,當使用者安裝更新時,您不需要強制他們授與權限,就可以將新的權限新增至更新的應用程式版本。
+
+
+
+
+
+
+</p>
+
+<p>
+ 如果應用程式在使用 M 開發人員預覽版的裝置上執行,
+<code><uses-permission-sdk-m></code> 的運作方式會和
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 相同。
+ 當他們安裝應用程式時,系統不會提示使用者授與任何權限,而應用程式會在需要時才要求權限。
+
+</p>
+
+<h3 id="prompting">
+ 提示授與權限
+</h3>
+
+<p>
+ 如果您的應用程式使用新的 M 開發人員預覽版權限模型,在執行 M 預覽版的裝置上初次啟動應用程式時,不會要求使用者授與所有權限。
+
+您的應用程式會在需要時才要求權限。
+應用程式要求權限時,系統會對使用者顯示對話方塊。
+
+</p>
+
+<p>
+ 如果您的應用程式在 SDK 22 以下版本的裝置上執行,應用程式會使用舊的權限模型。
+當使用者安裝應用程式時,會提示他們授與應用程式在其宣示說明中要求的所有權限,但標示為 <code><uses-permission-sdk-m></code> 的那些權限除外。
+
+
+</p>
+
+<h4 id="check-platform">檢查應用程式執行所在的平台</h4>
+
+<p>
+ 只有執行 M 開發人員預覽版的裝置上才支援此權限模型。
+呼叫這些方法之前,應用程式應該檢查 {@link android.os.Build.VERSION#CODENAME
+ Build.VERSION.CODENAME} 的值,驗證它執行所在的平台。
+
+如果裝置是執行 M 開發人員預覽版,
+{@link android.os.Build.VERSION#CODENAME CODENAME} 是 <code>"MNC"</code>。
+</p>
+
+<h4 id="check-for-permission">檢查應用程式是否具備所需權限</h4>
+
+<p>當使用者嘗試執行需要權限的操作時,應用程式會檢查它目前是否具備可執行此操作的權限。
+如要這麼做,應用程式可呼叫
+
+<code>Context.checkSelfPermission(<i>permission_name</i>)</code>。由於使用者可以隨時撤銷應用程式的權限,即使應用程式知道使用者已授與該權限,還是應該執行此檢查。
+
+
+例如,如果使用者想要使用應用程式拍攝相片,應用程式會呼叫 <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>。
+
+</p>
+
+<p class="table-caption" id="permission-groups">
+ <strong>表 1.</strong>權限和權限群組。</p>
+<table>
+ <tr>
+ <th scope="col">權限群組</th>
+ <th scope="col">權限</th>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CALENDAR</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CALENDAR</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.WRITE_CALENDAR</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CAMERA</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.CAMERA</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.CONTACTS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CONTACTS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_PROFILE</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_PROFILE</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.LOCATION</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.ACCESS_FINE_LOCATION</code>
+ </li>
+ <li>
+ <code>android.permission.ACCESS_COARSE_LOCATION</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.MICROPHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.RECORD_AUDIO</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.PHONE</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.READ_PHONE_STATE</code>
+ </li>
+ <li>
+ <code>android.permission.CALL_PHONE</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CALL_LOG</code>
+ </li>
+ <li>
+ <code>android.permission.WRITE_CALL_LOG</code>
+ </li>
+ <li>
+ <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
+ </li>
+ <li>
+ <code>android.permission.USE_SIP</code>
+ </li>
+ <li>
+ <code>android.permission.PROCESS_OUTGOING_CALLS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SENSORS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.BODY_SENSORS</code>
+ </li>
+ </ul>
+ <ul>
+ <li>
+ <code>android.permission.USE_FINGERPRINT</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>android.permission-group.SMS</code></td>
+ <td>
+ <ul>
+ <li>
+ <code>android.permission.SEND_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_SMS</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_WAP_PUSH</code>
+ </li>
+ <li>
+ <code>android.permission.RECEIVE_MMS</code>
+ </li>
+ <li>
+ <code>android.permission.READ_CELL_BROADCASTS</code>
+ </li>
+ </ul>
+ </td>
+ </tr>
+
+</table>
+
+<h4 id="request-permissions">必要時要求權限</h4>
+
+<p>如果應用程式還沒有所需的權限,應用程式會呼叫
+<code>Activity.requestPermissions(String[], int)</code> 方法以要求適當的權限。
+應用程式會傳遞它所需的權限,還有整數「要求代碼」。
+
+ 這種方法以非同步方式運作:它會立即傳回,並在使用者回應對話方塊後,系統會以該結果呼叫應用程式的回呼方法,傳遞應用程式傳遞給 <code>requestPermissions()</code> 的相同「要求代碼」。
+
+
+</p>
+
+ <p>下列程式碼會檢查應用程式是否具備讀取使用者聯絡人的權限,並在必要時要求權限。
+</p>
+
+<pre>
+if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
+ MY_PERMISSIONS_REQUEST_READ_CONTACTS);
+
+ // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
+ // app-defined int constant
+
+ return;
+}
+</pre>
+
+<h4 id="handle-response">處理權限要求回應</h4>
+
+<p>
+ 當應用程式要求權限時,系統會對使用者呈現對話方塊。
+當使用者回應時,系統會呼叫 <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> 並將使用者回應傳遞給它。
+
+您的應用程式需要覆寫該方法。將您傳遞給 <code>requestPermissions()</code> 的相同要求代碼傳遞給回呼。
+
+例如,如果應用程式要求 <code>READ_CONTACTS</code> 存取權,可能會有下列回呼方法:
+
+
+</p>
+
+<pre>
+@Override
+public void onRequestPermissionsResult(int requestCode,
+ String permissions[], int[] grantResults) {
+ switch (requestCode) {
+ case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ // permission was granted, yay! do the
+ // calendar task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'switch' lines to check for other
+ // permissions this app might request
+ }
+}
+</pre>
+
+ <p>如果使用者授與權限,系統就會將應用程式宣示說明所列出該功能區域的所有權限給予應用程式。
+如果使用者拒絕要求,您應該執行適當動作。
+例如,您可能會停用依存於此權限的任何選單動作。
+
+ </li>
+</p>
+
+<p>
+ 系統要求使用者授與權限時,使用者可選擇告知系統不要再次要求該權限。
+在上述情況下,當應用程式使用 <code>requestPermissions()</code> 要求該權限時,系統會立即拒絕要求。
+
+在這種情況下,如果使用者再次明確拒絕您的要求,系統會以相同的方式呼叫您的 <code>onRequestPermissionsResult()</code>。
+
+基於這個理由,您的應用程式不能假設已與使用者發生任何直接互動。
+
+</p>
+
+<h2 id="testing">測試執行階段權限</h2>
+
+
+<p>
+ 如果您的應用程式是以新的 M 開發人員預覽版為目標,您必須測試它是否能適當處理權限。
+您不能假設應用程式在執行時具備任何特定權限。
+應用程式初次啟動時,很可能不具備任何權限,且使用者可隨時撤銷或還原權限。
+
+
+</p>
+
+<p>
+ 您應該測試應用程式,確保它在所有權限情況下都能正常運作。
+使用 M 預覽版 SDK,我們現在提供 <a href="{@docRoot}tools/help/adb.html">Android 偵錯橋 (adb)</a> 命令,不管需要嘗試哪種權限設定都能讓您測試。
+
+
+
+</p>
+
+<h3>
+ 新的 adb 命令和選項
+</h3>
+
+<p>
+ M 預覽版 SDK 平台工具提供的數個命令可讓您測試應用程式如何處理權限。
+
+</p>
+
+<h4>
+ 連同權限一併安裝
+</h4>
+
+<p>
+ 您可以使用 <a href="{@docRoot}tools/help/adb.html#move"><code>adb
+ install</code></a> 命令的新 <code>-g</code> 選項,安裝應用程式並授與其宣示說明中列出的所有權限:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb install -g <path_to_apk>
+</pre>
+
+<h4>
+ 授與和撤銷權限
+</h4>
+
+<p>
+ 您可以使用新的 ADB <a href="{@docRoot}tools/help/adb.html#pm">套件管理員 (pm)</a> 命令,對安裝的應用程式授與和撤銷權限。此功能在自動化測試時非常實用。
+
+
+</p>
+
+<p>
+ 如要授與權限,可使用套件管理員的 <code>grant</code> 命令:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant <package_name> <permission_name>
+</pre>
+
+<p>
+ 例如,如要將可錄製音訊的權限授與 com.example.myapp 套件,請使用此命令:
+
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
+</pre>
+
+<p>
+ 如要撤銷權限,可使用套件管理員的 <code>revoke</code> 命令:
+</p>
+
+<pre class="no-pretty-print">
+$ adb pm revoke <package_name> <permission_name>
+</pre>
+
+<h2 id="best-practices">最佳做法</h2>
+
+<p>
+ 新的權限模型讓使用者有更順暢的體驗,並能輕鬆安裝應用程式且對應用程式執行的工作感到自在。
+
+建議使用下列最佳做法以充分利用新的模型。
+
+</p>
+
+
+<h3 id="bp-what-you-need">只要求您所需的權限</h3>
+
+<p>
+ 每次要求權限時,您都是在強迫使用者做出決定。
+ 如果使用者拒絕要求,就會減少您應用程式的功能。
+ 您應該儘可能減少提出這些要求的次數。
+</p>
+
+<p>
+ 例如,您的應用程式可經常使用<a href="{@docRoot}guide/components/intents-filters.html">意圖</a>來取得所需功能,而不是要求權限。
+
+如果您的應用程式需要使用手機的相機拍攝相片,應用程式可以使用 {@link
+ android.provider.MediaStore#ACTION_IMAGE_CAPTURE
+ MediaStore.ACTION_IMAGE_CAPTURE} 意圖。
+當您的應用程式執行意圖時,系統會提示使用者選擇已安裝的相機應用程式來拍攝相片。
+
+
+</p>
+
+<h3 id="bp-dont-overwhelm">
+ 別讓使用者無法承受
+</h3>
+
+<p>
+ 如果您讓使用者一次面對太多權限要求,可能會讓使用者無法承受而結束您的應用程式。您應該改為在需要時才要求權限。
+
+
+</p>
+
+<p>
+ 在某些情況下,您的應用程式可能必須具備一或多個權限。在那種情況下,在應用程式啟動時立即要求所有權限是合理的舉措。
+
+例如,如果您建立攝影應用程式,該應用程式會需要存取裝置相機。
+使用者初次啟動應用程式時,看到要求使用相機的權限不會被嚇到。
+
+但如果相同的應用程式具有與使用者聯絡人分享相片的功能,您可能「不」<em></em>應該在初次啟動時要求該權限。
+
+可以等到使用者嘗試使用「分享」功能時,再要求該權限。
+
+</p>
+
+<p>
+ 如果您的應用程式提供教學課程,在教學課程結束時要求應用程式的基本權限是合理的舉措。
+
+</p>
+
+<h3 id="bp-explain">
+ 說明需要權限的原因
+</h3>
+
+<p>
+ 當您呼叫
+<code>requestPermissions()</code> 時,系統顯示的權限對話方塊會說明您的應用程式想要的權限,但不會說明原因。
+在某些情況下,使用者可能會感到不解。
+ 在呼叫 <code>requestPermissions()</code> 前對使用者說明應用程式想要權限的原因是不錯的想法。
+
+</p>
+
+<p>
+ 例如,攝影應用程式可能想要使用定位服務,以便將相片加上地理標籤。
+一般使用者可能不明白相片可以包含定位資訊,而不明白為何攝影應用程式會想要知道位置。
+
+在這種情況下,在呼叫 <code>requestPermissions()</code>「之前」<em></em>,將此功能的相關資訊告訴使用者會是不錯的想法。
+
+
+</p>
+
+<p>
+ 您可以將這些要求與應用程式教學課程結合來完成此作業。教學課程可依序顯示應用程式的各項功能,並可以同時說明需要哪些權限。
+
+例如,攝影應用程式的教學課程可以示範「與聯絡人分享相片」功能,接著告訴使用者需要提供權限,應用程式才能看到使用者的聯絡人。
+
+
+接著,應用程式可以呼叫 <code>requestPermissions()</code>,要求使用者提供該存取權。
+當然,並非每位使用者都會依照教學課程執行動作,所以您仍需要在應用程式的正常操作期間檢查和要求權限。
+
+
+</p>
diff --git a/docs/html-intl/intl/zh-tw/preview/overview.jd b/docs/html-intl/intl/zh-tw/preview/overview.jd
new file mode 100644
index 0000000..63cde32
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/preview/overview.jd
@@ -0,0 +1,362 @@
+page.title=程式總覽
+page.metaDescription=歡迎使用 Android M 開發人員預覽版,本程式提供為新版 Android 測試和最佳化您應用程式所需的一切。
+page.image=images/cards/card-preview_16-9_2x.png
+page.tags="preview", "developer", "android"
+
+@jd:body
+
+<p>
+ 歡迎使用「Android M 開發人員預覽版」<strong></strong>,本程式提供為新版 Android 測試和最佳化您應用程式所需的一切。
+
+免費使用,您只要下載 M 開發人員預覽版工具,就能立即開始使用。
+
+</p>
+
+<div style="background-color:#eceff1;padding:1em;">
+<div class="wrap">
+ <div class="cols">
+ <div class="col-4of12">
+ <h5>
+ 硬體與模擬器系統映像
+ </h5>
+
+ <p>
+ 在 Nexus 5、6、9 和 Player (適用於電視) ,以及模擬器上執行和測試您的應用程式。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 最新的平台程式碼
+ </h5>
+
+ <p>
+ 我們將在預覽版期間提供多次更新,讓您能夠針對最新的平台變更進行測試。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 透過 OTA 傳遞更新
+ </h5>
+
+ <p>
+ 在您將裝置刷新為初始預覽版之後,就能以無線方式取得更新。
+
+ </p>
+ </div>
+ </div>
+
+ <div class="cols">
+
+
+ <div class="col-4of12">
+ <h5>
+ 新行為和功能
+ </h5>
+
+ <p>
+ 儘早開始開發以支援新的平台行為,例如新的執行階段權限模型和省電功能。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 開發人員限時優先回報問題
+ </h5>
+
+ <p>
+ 在前幾個星期內,我們將讓開發人員優先回報問題,因此請盡快測試並提供意見反應。
+
+ </p>
+ </div>
+
+ <div class="col-4of12">
+ <h5>
+ 意見反應與支援
+ </h5>
+
+ <p>
+ 使用<a href="https://code.google.com/p/android-developer-preview/">問題追蹤器</a>回報問題並提供意見反應。
+ 與 <a href="http://g.co/dev/AndroidMDevPreview">M 開發人員社群</a>中的其他開發人員聯絡。
+
+ </p>
+ </div>
+ </div>
+</div>
+</div>
+
+<!--
+<p>
+ With the M Developer Preview, you'll get an early start on testing your apps,
+ with enough time to make adjustments before the public platform release later
+ in the year. We'll provide several updates to the Preview tools in the weeks
+ ahead, so you can keep in sync with the latest changes as the platform moves
+ toward launch.
+</p>
+<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
+"Preview program timeline" id="timeline">
+<p>
+ You can help us improve the platform by <a href=
+ "https://code.google.com/p/android-developer-preview/">reporting issues</a>
+ through our feedback channels. This is especially
+ critical in the first month of the preview, when we’ll be giving priority to
+ developer-reported issues and feedback.
+</p> -->
+
+
+<h2 id="timeline">
+ 時間軸和更新
+</h2>
+<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
+<p>
+ M 開發人員預覽版可從 5 月 28 日開始執行,直到我們將在 2015 年第 3 季正式發行之前發行的最終版 Android M SDK。
+
+
+</p>
+
+<p>
+ 我們將在主要的開發里程碑為您的測試裝置提供更新。
+ 里程碑暫定如下
+</p>
+
+<ul>
+ <li>
+ <strong>預覽版 1</strong> (初始預覽版,五月下旬)、
+ </li>
+
+ <li>
+ <strong>預覽版 2</strong> (六月下旬/七月上旬) 及
+ </li>
+
+ <li>
+ <strong>預覽版 3</strong> (接近最終版,七月下旬)
+ </li>
+</ul>
+
+<p>
+ 這些更新最終會成為「最終版 SDK」<strong></strong> (稍後於第 3 季),為新版 Android 提供正式的 API,以及最終的系統行為和功能。
+
+
+</p>
+
+<p>
+ 當您在 Android M 上測試和開發時,強烈建議您在預覽版更新發行時立即更新,讓「您的開發環境保持在最新狀態」<strong></strong>。
+
+ 為了讓程序更簡單,我們將對更新為預覽版建置的裝置<strong>以無線 (OTA) 方式提供更新</strong>,還會提供您能手動下載和更新的系統映像。
+
+
+</p>
+<p class="note">
+ <strong>注意:</strong>最終版 SDK 與系統映像無法以 OTA 方式提供,將必須<strong>以手動方式更新</strong>至您的測試裝置。</strong>
+
+
+</p>
+
+<p>
+ 我們將透過 <a href="http://android-developers.blogspot.com/">Android 開發人員部落格</a>,還有本網站與 <a href="http://g.co/dev/AndroidMDevPreview">Android M 開發人員社群</a>來通知您有可用的預覽版更新。
+
+
+</p>
+
+<h2 id="preview_tools">
+ 預覽版新增功能
+</h2>
+
+<p>
+ M 開發人員預覽版包含您針對各種不同螢幕大小、網路技術、 CPU/GPU 晶片組及硬體架構,測試現有應用程式所需的一切。
+
+
+</p>
+
+<h4>
+ SDK 工具
+</h4>
+
+<p>
+ 您可以透過 <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a> 中的「SDK 管理器」下載以下元件:
+</p>
+
+<ul>
+ <li>M 開發人員預覽版 <strong>SDK 工具</strong>
+ </li>
+
+ <li>M 開發人員預覽版<strong>模擬器系統映像</strong> (32 位元和 64 位元)
+
+ </li>
+
+ <li>M 開發人員預覽版<strong>模擬器系統映像 (適用於 Android TV)</strong> (32 位元)
+
+ </li>
+</ul>
+
+<h4>
+ 硬體系統映像
+</h4>
+
+<p>
+ 您可以從<a href="download.html">下載頁面</a>下載適用於 Nexus 裝置的以下硬體系統映像:
+
+</p>
+
+<ul>
+ <li>
+ <strong>Nexus 5</strong> (GSM/LTE)“hammerhead”裝置系統映像
+ </li>
+
+ <li>
+ <strong>Nexus 6</strong>“shamu”裝置系統映像
+ </li>
+
+ <li>
+ <strong>Nexus 9</strong> (Wi-Fi)“volantis”裝置系統映像
+ </li>
+
+ <li>
+ <strong>Nexus Player</strong> (Android TV)“fugu”裝置系統映像
+ </li>
+</ul>
+
+<h4>
+ 文件和範例程式碼
+</h4>
+
+<p>
+ 這些文件資源可協助您瞭解預覽版:
+</p>
+
+<ul>
+ <li>
+ <a href="setup-sdk.html">設定 SDK</a> 涵蓋開始使用的逐步指示。
+
+ </li>
+
+ <li>
+ <a href="{@docRoot}preview/testing/guide.html">測試指南</a>與<a href="behavior-changes.html">行為變更</a>指出要測試的主要區域。
+ </li>
+
+ <li>新 API 的文件,包括 <a href="api-overview.html">API 總覽</a>、可下載的 <a href="{@docRoot}preview/download.html#docs">API 參考資料</a>以及主要功能 (例如<a href="{@docRoot}preview/features/runtime-permissions.html">權限</a>、<a href="{@docRoot}preview/backup/index.html">應用程式備份</a>及其他功能) 的詳細開發人員指南。
+
+
+
+
+ </li>
+
+ <li>
+ 示範如何支援權限和其他新功能的<a href="{@docRoot}preview/samples.html">範例程式碼</a>。
+
+ </li>
+
+ <li>
+ 適用於目前 M 開發人員預覽版的<a href="{@docRoot}preview/support.html#release-notes">版本資訊</a>,包括變更資訊與差異報告。
+
+ </li>
+</ul>
+
+<h4>
+ 支援資源
+</h4>
+
+<p>
+ 在 M 開發人員預覽版上測試和開發時,請使用以下支援資源:
+
+</p>
+
+<ul>
+ <li><a href="https://code.google.com/p/android-developer-preview/">M 開發人員預覽版問題追蹤器</a>是您的<strong>主要意見反應</strong>管道。
+
+您可以透過問題追蹤器來回報錯誤、效能問題及一般意見反應。
+您也可以檢查<a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">已知問題</a>
+和尋找因應方式步驟。
+ </li>
+
+ <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 開發人員社群</a>是您能<strong>與其他 Android M 開發人員聯絡</strong>的 Google+ 社群。您可以分享有關 Android M 的觀察或想法,或尋找解答。
+
+
+
+ </li>
+</ul>
+
+
+<h2 id="preview_apis_and_publishing">
+ 目標設定、預覽版 API 及發行
+</h2>
+
+<p>
+ Android M 開發人員預覽版是開發專用的版本,而且<strong>沒有標準的 API 層級</strong>。
+如果您想要選擇退出相容性行為以測試您的應用程式 (強烈建議),您可以將應用程式的 <code><a href=
+ "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code> 設定為 <code>“MNC”</code>,就能以 M 開發人員預覽版為目標。
+
+
+
+</p>
+
+<p>
+ Android M 開發人員預覽版提供<strong>預覽版 API</strong> — 在最終版 SDK (目前規劃在 2015 年第三季) 發行之前的都不是正式 API。
+
+這表示您可以預期 API 會隨時間而有些許變更,特別是程式一開始的幾週。<strong></strong>
+
+我們會將 Android M 開發人員預覽版每次更新的變更摘要提供給您。
+
+</p>
+
+<p class="note">
+ 請注意,雖然預覽版 API 可能會改變,但例如執行階段權限和省電功能等基本系統行為,均已穩定且能夠立即測試。
+
+
+</p>
+
+<p>
+ 在發行方面,Google Play 會<strong>禁止您發行以 M 開發人員預覽版為目標的應用程式</strong>。
+當 Android M 最終版 SDK 推出時,您將能夠以正式 Android M API 層級為目標,並將您的應用程式發行至 Google Play。
+
+同時,您可以透過電子郵件或直接從您的網站下載,來對測試者散佈以 Android M 為目標的應用程式。
+
+
+</p>
+
+<h2 id="get_started">
+ 如何開始
+</h2>
+
+<p>
+ 如要開始測試您的應用程式:
+</p>
+
+<ol>
+ <li>檢閱 <a href="{@docRoot}preview/api-overview.html">API 總覽</a>與<a href="{@docRoot}preview/behavior-changes.html">行為變更</a>,以瞭解新增功能,還有它會如何影響您的應用程式。
+
+特別是瞭解新的<a href="{@docRoot}preview/features/runtime-permissions.html">執行階段權限</a>模型、省電功能以及自動化備份。
+
+
+ </li>
+
+ <li>依照<a href="{@docRoot}preview/setup-sdk.html">設定預覽版 SDK</a> 的指示來設定您的環境,並設定測試裝置。
+
+
+ </li>
+
+ <li>依照<a href="https://developers.google.com/android/nexus/images">刷新指示</a>,針對 Nexus 5、6、9 及 Player 刷新最新的 M 開發人員預覽版系統映像。
+
+在您刷新開發裝置之後,預覽版更新將以無線 (OTA) 更新</a>的方式提供。
+
+ </li>
+
+ <li>下載 <a href="{@docRoot}preview/download.html#docs">M 預覽版 API 參考資料</a>與 <a href="{@docRoot}preview/samples.html">M 預覽版範例</a>,以深入瞭解新的 API 功能以及如何在您的應用程式中運用。
+
+
+
+ </li>
+
+ <li>加入 <a href="http://g.co/dev/AndroidMDevPreview">Android M 開發人員社群</a>以取得最新消息,並與其他使用新平台的開發人員聯絡。
+
+
+ </li>
+</ol>
+
+<p>
+ 感謝您參與 Android M 開發人員預覽版程式!
+</p>
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/about/versions/android-4.3.jd b/docs/html/about/versions/android-4.3.jd
index e18c285..2496854 100644
--- a/docs/html/about/versions/android-4.3.jd
+++ b/docs/html/about/versions/android-4.3.jd
@@ -1029,7 +1029,7 @@
android.app.Instrumentation#getUiAutomation Instrumentation.getUiAutomation()}. In order
for this to work, you must supply the {@code -w} option with the {@code instrument} command
when running your {@link android.test.InstrumentationTestCase} from <a
-href="{@docRoot}tools/help/adb.html#am">{@code adb shell}</a>.</p>
+href="{@docRoot}tools/help/shell.html#am">{@code adb shell}</a>.</p>
<p>With the {@link android.app.UiAutomation} instance, you can execute arbitrary events to test
your app by calling {@link android.app.UiAutomation#executeAndWaitForEvent
diff --git a/docs/html/design/tv/index.jd b/docs/html/design/tv/index.jd
index def1286..38e5b79 100644
--- a/docs/html/design/tv/index.jd
+++ b/docs/html/design/tv/index.jd
@@ -4,6 +4,12 @@
page.image=design/tv/images/apps-games-rows.jpg
@jd:body
+<a class="notice-designers" style="clear:none" href="http://www.google.com/design/spec-tv">
+ <div>
+ <h3>Material Design</h3>
+ <p>Android TV Design Guidelines</p>
+ </div>
+</a>
<p>The Android TV platform user interface provides the launch pad for your app's big screen
experience. It's important to understand how your app is presented in the main user interface and
diff --git a/docs/html/design/wear/context.jd b/docs/html/design/wear/context.jd
index 688806f..7a0baf8 100644
--- a/docs/html/design/wear/context.jd
+++ b/docs/html/design/wear/context.jd
@@ -2,19 +2,19 @@
@jd:body
<style>
-div.slide-wrapper {
+.slide-wrapper {
width:780px;
overflow:visible;
}
-div.slide {
+.slide {
width:370px;
float:left;
margin:0 20px 0 0;
}
-div.slide p {
+.slide p {
height:40px;
}
-div.slide img {
+.slide img {
height: 208px;
}
</style>
@@ -140,8 +140,8 @@
<div class="slide">
<h2>Location-based Query</h2>
-<p>Ask things like, "Are there any picnic tables free at the park?" and get answers from
-people who are there.</p>
+<p>Ask questions like, "Are there any picnic tables free at the park?" and get answers in real-time
+from people in the area.</p>
<img src="{@docRoot}design/media/wear/ContextualExample.015.png" alt=""
srcset="{@docRoot}design/media/wear/ContextualExample.015.png 1x,
{@docRoot}design/media/wear/ContextualExample.015_2x.png 2x" />
@@ -149,4 +149,6 @@
-</div>
\ No newline at end of file
+</div>
+
+<p style="clear:both;height:0"> </p>
\ No newline at end of file
diff --git a/docs/html/design/wear/creative-vision.jd b/docs/html/design/wear/creative-vision.jd
index 0955240..36a87eb 100644
--- a/docs/html/design/wear/creative-vision.jd
+++ b/docs/html/design/wear/creative-vision.jd
@@ -25,34 +25,29 @@
<div class="page-vision">
- <img src="{@docRoot}design/media/wear/vision_traffic.png" width="147" height="147" />
-
<h2 id="Launched">Launched automatically</h2>
+ <img src="{@docRoot}design/media/wear/vision_traffic.png" width="147" height="147" />
<p>Most people are used to launching apps by clicking an icon. Android Wear is different. Wearable apps are aware of the user’s context - time, location, physical activity, and so on. The apps use this information to insert cards into the stream when they become relevant. This makes Android Wear timely, relevant and very specific.</p>
</div>
<div class="page-vision">
- <img src="{@docRoot}design/media/wear/vision_navigation.png" width="147" height="147" />
-
<h2 id="Glanceable">Glanceable</h2>
+ <img src="{@docRoot}design/media/wear/vision_navigation.png" width="147" height="147" />
<p>A classic wrist watch is designed to let you see the time in a split second and get on with what you were doing. Designing for Android Wear is no different. The less time it takes to use your software, the more time the user can be present in whatever they are doing. Android wear is fast, sharp, and immediate.</p>
</div>
<div class="page-vision">
- <img src="{@docRoot}design/media/wear/vision_voice.png" width="147" height="147" style="border: 1px solid #ddd;" />
-
<h2 id="SuggestDemand">All about suggest and demand</h2>
+ <img src="{@docRoot}design/media/wear/vision_voice.png" width="147" height="147" style="border: 1px solid #ddd;" />
<p>Android Wear is like a great personal assistant: it knows you and your preferences, it only interrupts you when absolutely necessary, and it’s always on hand to provide a ready answer. Android Wear is helpful, respectful, and responsive.</p>
</div>
<div class="page-vision">
- <img src="{@docRoot}design/media/wear/vision_music.png" width="147" height="147" />
-
<h2 id="Interaction">Zero or low interaction</h2>
+ <img src="{@docRoot}design/media/wear/vision_music.png" width="147" height="147" />
<p>Staying true to the strengths afforded by a smaller form factor, Android Wear focuses on simple interactions, only requiring input by the user when absolutely necessary. Most inputs are based around touch swipes or voice, and inputs requiring fine-grained finger movements are avoided. Android Wear is gestural, simple, and fast.</p>
</div>
<p>By providing a smart connection to the rest of the world while respecting the user’s attention, Android Wear feels personal and global, simple and smart, unobtrusive and ever-ready. Applications that represent these principles will feel most at home in the overall Android Wear experience.</p>
<p>Third party apps extend Android Wear to be more specialized and helpful throughout the day. Installing apps are a way for the user to tell the Android Wear how to do that.</p>
-
diff --git a/docs/html/design/wear/patterns.jd b/docs/html/design/wear/patterns.jd
index e56ac2d..0436cf5 100644
--- a/docs/html/design/wear/patterns.jd
+++ b/docs/html/design/wear/patterns.jd
@@ -46,11 +46,9 @@
<h2 id="Dismissing" style="clear:both">Dismissing cards</h2>
- <img src="{@docRoot}design/media/wear/dismiss_cards.png" height="147">
-
<p>Swiping from left to right on a card causes it to be dismissed from the stream. Dismissed cards may return when they next have relevant information. State is synced between the Android Wear context stream and the notifications on the Android handheld device, so dismissing from one causes an automatic dismissal from the other.</p>
-
+<img src="{@docRoot}design/media/wear/dismiss_cards.png" height="147">
<h2 id="Actions" style="clear:both">Action buttons</h2>
@@ -162,12 +160,11 @@
<h2 id="Selection" style="clear:both">Selection List</h2>
- <img src="{@docRoot}design/media/wear/selection_list.png" width="147" height="147" style="float:right;margin:0 0 20px 40px;border:1px solid #ddd">
+ <img src="{@docRoot}design/media/wear/selection_list.png" width="147" height="147" style="float:left;margin:0 0 20px 40px;border:1px solid #ddd">
<p>Choosing an item from a list is a common interaction. The Selection List pattern (available as the <a
href="{@docRoot}training/wearables/apps/layouts.html#UiLibrary"><code>WearableListView</code></a> component) creates a simple list optimized for ease of use on a small screen where the focused item snaps to the center of the screen and a single tap selects. This widget is recommended as a common pattern for selecting items. It is used throughout the system UI, including in the list that can be accessed by swiping up on the cue card.</p>
-
<p>Of course, it is possible for Android Wear apps to extend themselves beyond the familiarities of these patterns. For a deeper look at the options available, see the <a href="{@docRoot}design/wear/structure.html">App Structure</a> guide.</p>
<a class="notice-developers left" href="{@docRoot}training/wearables/ui/lists.html">
@@ -176,3 +173,5 @@
<p>Creating Lists</p>
</div>
</a>
+
+<p style="clear:both;height:0"> </p>
diff --git a/docs/html/design/wear/style.jd b/docs/html/design/wear/style.jd
index bb559fe..75bd65f 100644
--- a/docs/html/design/wear/style.jd
+++ b/docs/html/design/wear/style.jd
@@ -48,19 +48,18 @@
</div>
-
- <img src="{@docRoot}design/media/wear/low_info_card.png" width="147" height="147"
- style="float:right;margin:29px 0 20px 40px">
-
<h2 id="InfoDensity" style="margin-top:0" >Low Information Density</h2>
+<img src="{@docRoot}design/media/wear/low_info_card.png" width="147" height="147"
+style="float:left;margin:5px 20px 20px 0">
+
<p>Cards should be designed to be glanceable in a split second, just like reading the time on a traditional watch. In most cases a pairing of an icon and value, or a title and short caption should be enough to convey a meaningful message. Note that the background photo should also be used to convey information; backgrounds that change to reflect and support the primary message in the card work great. For example, in the case illustrated to the right, a suitable background image is chosen to reflect the severity of current traffic conditions. This is not just a nice piece of attention to detail; the background actually reinforces the message and makes the content more glanceable.</p>
-<img src="{@docRoot}design/media/wear/separate_info_cards.jpg" height="147"
- style="float:right;margin:29px 0 20px 40px">
<h2 id="Chunks">Separate Information into Chunks</h2>
+<img src="{@docRoot}design/media/wear/separate_info_cards.jpg" height="147"
+ style="float:right;margin:5px 0 20px 20px">
<p>In cases where additional information is absolutely necessary, don’t crowd out a card layout to the point where glanceability is affected. Instead, add an additional <a href="{@docRoot}design/wear/patterns.html#Pages">page</a> (or multiple pages, if needed) to the right of the main card in the stream to which the user can swipe for more information. See also <a
href="{@docRoot}design/wear/patterns.html#Continuing">Continuing activities on phone</a>.</p>
@@ -73,21 +72,19 @@
-<img src="{@docRoot}design/media/wear/clear_bold_type.jpg" height="147"
- style="float:left;margin:19px 40px 20px 0">
-
<h2 id="Typography" >Use Clear, Bold Typography</h2>
+<img src="{@docRoot}design/media/wear/clear_bold_type.jpg" height="147"
+ style="float:left;margin:5px 20px 20px 0">
<p>The system font is Roboto Condensed, with Regular and Light variants. Text should adhere to the size and color recommendations (see the UI Toolkit in the <a href="{@docRoot}design/downloads/index.html#Wear">Downloads</a> page). In general, text should be displayed as large as possible. Your goal should be to convey maximum information with minimum fuss.</p>
<h2 id="Branding" style="clear:both" >Use Consistent Branding and Color</h2>
-<p>The app icon is used to identify and brand your application. The icon is optional but when present always appears in the same location, overhanging the top right edge of the card. Note that app icons or branding should not be displayed in the background photo, which is reserved to display an image relevant to the information on the card.</p>
-
-
<img src="{@docRoot}design/media/wear/copywrite.png" height="147"
- style="float:left;margin:19px 40px 20px 0">
+ style="float:right;margin:0 20px 0 20px">
+
+<p style="margin-bottom: 60px">The app icon is used to identify and brand your application. The icon is optional but when present always appears in the same location, overhanging the top right edge of the card. Note that app icons or branding should not be displayed in the background photo, which is reserved to display an image relevant to the information on the card.</p>
<h2 id="Copywrite" >Copywrite Sparingly</h2>
@@ -98,18 +95,11 @@
<p>Wearables are personal devices by nature, but they are not completely private. If your notification serves content that may be particularly sensitive or embarrassing (such as notifications from a dating app or a medical status report), consider not displaying all of the information in a peek card. A notification could place the sensitive information on a second page that must be swiped to, or an application could show different amounts of detail in peek and focused card positions.</p>
-
- <img src="{@docRoot}design/media/wear/confirmation.png" height="147"
- style="float:left;margin:29px 40px 20px 0">
-
-
<h2 id="ConfirmAnim">Confirmation Animations</h2>
+<img src="{@docRoot}design/media/wear/confirmation.png" height="147"
+ style="float:left;margin:5px 20px 20px 0">
+
<p>If your app allows the user to perform an action, it is necessary to provide positive feedback. Show a generic confirmation animation or create your own. A confirmation animation is an opportunity to express your app’s character and insert a moment of delight for your user. Keep animations short (less than 1000ms) and simple. Animating the confirmation icon is an effective way of transitioning the user to a new state after completing an action.</p>
-
-
-
-
-
-
+<p style="clear:both;height:0"> </p>
\ No newline at end of file
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
index 2def05b..e018523 100644
--- a/docs/html/design/wear/watchfaces.jd
+++ b/docs/html/design/wear/watchfaces.jd
@@ -4,7 +4,7 @@
<!-- developer docs box -->
<a class="notice-developers right" href="{@docRoot}training/wearables/watch-faces/index.html"
- style="clear:left;margin-bottom:90px">
+ style="clear:left">
<div>
<h3>Developer Docs</h3>
<p>Creating Watch Faces</p>
@@ -22,7 +22,7 @@
<p>Follow the guidelines in this page to design your custom watch faces.</p>
<!-- H2 creative vision -->
-<div style="float:right;margin-top:-100px;margin-bottom:20px;margin-left:20px">
+<div style="float:right;margin-bottom:20px;margin-left:20px">
<img src="{@docRoot}design/media/wear/Render_Next.png"
width="200" height="195" alt="" style="margin-right:5px"/><br/>
<img src="{@docRoot}design/media/wear/Render_Interactive.png"
@@ -137,44 +137,39 @@
of screen available on the device. Consider the best design for your watch faces on all
screens.</p>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>Reduced color space</h3>
- <p>Some displays use a reduced color space in ambient mode to save power.</p>
- <p>One reduced color space power saving method is to use a "low-bit" mode. In low-bit mode,
- the available colors are limited to black, white, blue, red, magenta, green, cyan, and yellow.
- When designing for low-bit ambient mode, use a black or a white background. For OLED screens,
- you must use a black background. Non-background pixels must be less than 10 percent of total
- pixels. You can use low-bit color for up to 5 percent of pixels on screens that support it.
- You should also disable antialiasing in your paint styles for this mode. Make sure to test
- your design on devices with low-bit ambient mode.</p>
- <p>Other displays save power in ambient mode by not producing any color. When designing for
- displays which do not use color in ambient mode, the background may be either black or
- white.</p>
-</div>
-<div class="col-4">
+<div style="float:right;margin-bottom:20px;margin-left:20px">
<img src="{@docRoot}design/media/wear/Render_LowBit.png" width="200"
height="" alt="" style="margin-top:45px;margin-left:13px">
</div>
-</div>
+<h3>Reduced color space</h3>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>Burn protection techniques</h3>
- <p>When designing for OLED screens, you should consider power efficiency and the screen
- burn-in effect. When these screens are in ambient mode, the system shifts the contents of
- the screen periodically by a few pixels to avoid pixel burn-in. Do not use large blocks of
- pixels in your ambient mode designs and keep 95% of the pixels black. Replace solid shapes in
- your regular ambient mode designs with outlined shapes in burn-protected ambient mode. Also
- replace filled images with pixel patterns. For analog watch face designs, hollow out the center
- where the hands meet to avoid pixel burn-in in this mode.</p>
-</div>
-<div class="col-4">
+<p>Some displays use a reduced color space in ambient mode to save power.</p>
+<p>One reduced color space power saving method is to use a "low-bit" mode. In low-bit mode,
+the available colors are limited to black, white, blue, red, magenta, green, cyan, and yellow.
+When designing for low-bit ambient mode, use a black or a white background. For OLED screens,
+you must use a black background. Non-background pixels must be less than 10 percent of total
+pixels. You can use low-bit color for up to 5 percent of pixels on screens that support it.
+You should also disable antialiasing in your paint styles for this mode. Make sure to test
+your design on devices with low-bit ambient mode.</p>
+<p>Other displays save power in ambient mode by not producing any color. When designing for
+displays which do not use color in ambient mode, the background may be either black or
+white.</p>
+
+
+<h3>Burn protection techniques</h3>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
<img src="{@docRoot}design/media/wear/Render_1Bit.png" width="200"
height="" alt="" style="margin-top:-10px;margin-left:13px">
</div>
-</div>
+<p>When designing for OLED screens, you should consider power efficiency and the screen
+burn-in effect. When these screens are in ambient mode, the system shifts the contents of
+the screen periodically by a few pixels to avoid pixel burn-in. Do not use large blocks of
+pixels in your ambient mode designs and keep 95% of the pixels black. Replace solid shapes in
+your regular ambient mode designs with outlined shapes in burn-protected ambient mode. Also
+replace filled images with pixel patterns. For analog watch face designs, hollow out the center
+where the hands meet to avoid pixel burn-in in this mode.</p>
<h2 id="SystemUI">Accomodate System UI Elements</h2>
@@ -183,9 +178,11 @@
user the status of the wearable and show notifications from services on the user's phone. Try
to keep critical elements in your watch face designs from being obscured by the UI elements.</p>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>Cards</h3>
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/CardsRender_Build.png" width="200"
+ height="" alt="" style="margin-top:20px;margin-left:13px">
+</div>
+<h3>Cards</h3>
<p>Cards are the notification system that bridges information between the wearable and a
mobile device. Cards are also how most applications communicate with users. The user will be
notified on the wearable about items such as emails and messages. As a watch face developer,
@@ -201,16 +198,13 @@
the bottom half of the face should leverage the small peek card instead.</p>
<p>The system notifies your watch face when the bounds of a peek card change, so you can
rearrange the elements in your design if necessary.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/CardsRender_Build.png" width="200"
- height="" alt="" style="margin-top:20px;margin-left:13px">
-</div>
-</div>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>Indicators</h3>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/Indicators_Cropped.png" width="200"
+ height="" alt="" style="margin-top:0px;margin-left:13px">
+</div>
+<h3>Indicators</h3>
<p>Indicators tell the user the status of the wearable, such as charging and airplane mode.
When designing a watch face, consider how the indicator will fall over the watch face.</p>
<p>The indicators can be placed in several fixed locations on the wearable. If you have a
@@ -218,16 +212,12 @@
position the status icons or the hotword on the bottom of the screen, the system forces small
peek cards. If the edge of the watch face contains strong visual elements, such as
ticks or numbers, place the indicators on the center of the screen.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/Indicators_Cropped.png" width="200"
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/Hotword_Cropped.png" width="200"
height="" alt="" style="margin-top:0px;margin-left:13px">
</div>
-</div>
-
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>The hotword</h3>
+<h3>The hotword</h3>
<p>The hotword is the phrase "OK Google", which tells the user that they can interact with
the watch using voice commands. When a user turns on the wearable, the hotword appears on
the screen for a few seconds.</p>
@@ -236,12 +226,6 @@
watch face. Finally, background protection for the hotword and the indicators should be
turned on unless your design is tailored to have these elements appear on top of them, for example
using dark solid colors with no patterns.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/Hotword_Cropped.png" width="200"
- height="" alt="" style="margin-top:0px;margin-left:13px">
-</div>
-</div>
<p>For more information about measurements and positioning of system UI elements, see
<a href="#SpecsAssets">Specifications and Assets</a>.</p>
@@ -253,24 +237,27 @@
<p>Your watch face can show users contextually relevant data and react to it by changing styles
and colors in your design.</p>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>What do you want your user to know?</h3>
+<h3>What do you want your user to know?</h3>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/Render_Saturn.png" width="200"
+ height="" alt="" style="margin-top:-10px;margin-left:13px">
+</div>
+
<p>The first step in designing a data-integrated watch face is to define a conceptual user
outcome based on available data. First, generate a strong concept or outcome you believe is
supported by real user needs. What do you want your users to know after they have glanced
at your design? Once you have identified your outcome, you need to determine how to obtain
the required data.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/Render_Saturn.png" width="200"
+
+<div style="clear:both;"/>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/Render_Episode.png" width="200"
height="" alt="" style="margin-top:-10px;margin-left:13px">
</div>
-</div>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>A watch dial is a timeline; add data to it</h3>
+<h3>A watch dial is a timeline; add data to it</h3>
<p>Your watch face concept may include use of data beyond time, such as weather, calendar
and fitness data. Consider the inclusion of data integration creatively. Avoid simply
overlaying a time-based watch face with extra data. Rather, think about how the data can
@@ -278,16 +265,13 @@
watch face as a clock with an indication of the current temperature in degrees overlayed,
you might design a watch face that describes how the temperature will change over the
course of the day.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/Render_Episode.png" width="200"
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+ <img src="{@docRoot}design/media/wear/Render_Albumem.png" width="200"
height="" alt="" style="margin-top:-10px;margin-left:13px">
</div>
-</div>
-<div class="cols" style="margin-top:20px">
-<div class="col-9">
- <h3>Stick to one message</h3>
+<h3>Stick to one message</h3>
<p>Once you have solidified your conceptual direction or desired outcome, you will need to
begin visualizing your watch face. The strongest watch face designs are highly glanceable
and deliver a singular expression of data. In order to identify your singular message, you
@@ -295,12 +279,6 @@
an entire month of calendar events, you might decide to display only the next
upcoming event. By a process of reduction, you should arrive at a powerful singular
expression of data to include in your design.</p>
-</div>
-<div class="col-4">
- <img src="{@docRoot}design/media/wear/Render_Albumem.png" width="200"
- height="" alt="" style="margin-top:-10px;margin-left:13px">
-</div>
-</div>
<h3>Begin with some insight and test as you go</h3>
<p>Make sure your approach begins with insight into the needs and expectations of your users.
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/components/intents-common.jd b/docs/html/guide/components/intents-common.jd
index 167ebde..8aa5fa9 100644
--- a/docs/html/guide/components/intents-common.jd
+++ b/docs/html/guide/components/intents-common.jd
@@ -2236,7 +2236,7 @@
<p>For more information, see
-<a href="{@docRoot}tools/help/adb.html#am">Using activity manager (am)</a>.</p>
+<a href="{@docRoot}tools/help/shell.html#am">ADB Shell Commands</a>.</p>
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/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b06da56..63eee96 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -549,6 +549,22 @@
which indicates whether the screen is long.</p>
</td>
</tr>
+ <tr id="ScreenRoundQualifier">
+ <td>Round screen</td>
+ <td>
+ <code>round</code><br/>
+ <code>notround</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code round}: Round screens, such as a round wearable device</li>
+ <li>{@code notround}: Rectangular screens, such as phones or tablets</li>
+ </ul>
+ <p><em>Added in API level 23.</em></p>
+ <p>Also see the {@link android.content.res.Configuration#isScreenRound()} configuration
+method, which indicates whether the screen is round.</p>
+ </td>
+ </tr>
<tr id="OrientationQualifier">
<td>Screen orientation</td>
<td>
diff --git a/docs/html/guide/topics/security/permissions.jd b/docs/html/guide/topics/security/permissions.jd
index 6f919da..cfab3c9 100644
--- a/docs/html/guide/topics/security/permissions.jd
+++ b/docs/html/guide/topics/security/permissions.jd
@@ -52,9 +52,7 @@
<em>permissions</em> they need for additional capabilities not provided by
the basic sandbox. Applications statically declare the permissions they
require, and the Android system prompts the user for consent at the time the
-application is installed. Android has no mechanism for granting permissions
-dynamically (at run-time) because it complicates the user experience to the
-detriment of security.</p>
+application is installed.</p>
<p>The application sandbox does not depend on the technology used to build
an application. In particular the Dalvik VM is not a security boundary, and
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index d972c47..b2f98ad 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -907,11 +907,7 @@
<p>To get started, your layout must include a {@link android.view.ViewGroup} in which you place
each {@link android.app.Fragment} associated with a tab. Be sure the {@link android.view.ViewGroup}
has a resource ID so you can reference it from your code and swap the tabs within it.
-Alternatively, if the tab content will fill the activity layout, then your activity doesn't need a
-layout at all (you don't even need to call {@link android.app.Activity#setContentView
-setContentView()}). Instead, you can place each fragment in the default root view, which you can
-refer to with the {@code android.R.id.content} ID.</p>
-
+</p>
<p>Once you determine where the fragments appear in the layout, the basic procedure to add tabs
is:</p>
diff --git a/docs/html/guide/topics/ui/controls/text.jd b/docs/html/guide/topics/ui/controls/text.jd
index 9474dee..c11dc32 100644
--- a/docs/html/guide/topics/ui/controls/text.jd
+++ b/docs/html/guide/topics/ui/controls/text.jd
@@ -172,7 +172,7 @@
are any subsequent <a
href="{@docRoot}reference/android/view/View.html#attr_android:focusable">{@code
android:focusable}</a> fields. If any focusable fields are found following this one, the system
-applies the (@code actionNext} action to the current {@link android.widget.EditText} so the user can
+applies the {@code "actionNext"} action to the current {@link android.widget.EditText} so the user can
select Next to move to the next field. If there's no subsequent focusable field, the system applies
the {@code "actionDone"} action. You can override this by setting the <a
href="{@docRoot}reference/android/widget/TextView.html#attr_android:imeOptions">{@code
@@ -263,7 +263,7 @@
<p>If you want to provide suggestions to users as they type, you can use a subclass of {@link
android.widget.EditText} called {@link android.widget.AutoCompleteTextView}. To implement
-auto-complete, you must specify an (@link android.widget.Adapter) that provides the text
+auto-complete, you must specify an {@link android.widget.Adapter} that provides the text
suggestions. There are several kinds of adapters available, depending on where the data is coming
from, such as from a database or an array.</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/images/tools/eclipse-notepad-pre-import--structure.png b/docs/html/images/tools/eclipse-notepad-pre-import--structure.png
new file mode 100644
index 0000000..b9c3814
--- /dev/null
+++ b/docs/html/images/tools/eclipse-notepad-pre-import--structure.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-destination-dir.png b/docs/html/images/tools/studio-import-destination-dir.png
new file mode 100644
index 0000000..d1c6c70
--- /dev/null
+++ b/docs/html/images/tools/studio-import-destination-dir.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-options.png b/docs/html/images/tools/studio-import-options.png
new file mode 100644
index 0000000..f14eca0
--- /dev/null
+++ b/docs/html/images/tools/studio-import-options.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-project-structure-android.png b/docs/html/images/tools/studio-import-project-structure-android.png
new file mode 100644
index 0000000..4cd7186
--- /dev/null
+++ b/docs/html/images/tools/studio-import-project-structure-android.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-project-structure-project.png b/docs/html/images/tools/studio-import-project-structure-project.png
new file mode 100644
index 0000000..c7ffda8
--- /dev/null
+++ b/docs/html/images/tools/studio-import-project-structure-project.png
Binary files differ
diff --git a/docs/html/images/tools/studio-import-summary.png b/docs/html/images/tools/studio-import-summary.png
new file mode 100644
index 0000000..a85e339
--- /dev/null
+++ b/docs/html/images/tools/studio-import-summary.png
Binary files differ
diff --git a/docs/html/images/tools/studio-select-project-forimport.png b/docs/html/images/tools/studio-select-project-forimport.png
new file mode 100644
index 0000000..c6a3599
--- /dev/null
+++ b/docs/html/images/tools/studio-select-project-forimport.png
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..c5b0b85 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": {
@@ -1602,7 +1611,8 @@
"title": "",
"resources": [
"training/enterprise/work-policy-ctrl.html",
- "samples/BasicManagedProfile/index.html"
+ "samples/BasicManagedProfile/index.html",
+ "https://www.youtube.com/watch?v=j3QC6hcpy90"
]
},
"tools/performance/rendering": {
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/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 9a834506..7b1169f 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -30,21 +30,22 @@
-sdk.linux_download=android-sdk_r24.3.2-linux.tgz
-sdk.linux_bytes=309138263
-sdk.linux_checksum=4a10e62c5d88fd6c2a69db12348cbe168228b98f
+sdk.linux_download=android-sdk_r24.3.3-linux.tgz
+sdk.linux_bytes=309109716
+sdk.linux_checksum=cd4cab76c2e3d926b3495c26ec56c831ba77d0d0
-sdk.mac_download=android-sdk_r24.3.2-macosx.zip
-sdk.mac_bytes=98329772
-sdk.mac_checksum=8609b92e26e9bd5796f771138c6b222b6c0cb474
+sdk.mac_download=android-sdk_r24.3.3-macosx.zip
+sdk.mac_bytes=98330824
+sdk.mac_checksum=41f0f3e76d6868018740e654aefb04fd765c357d
-sdk.win_download=android-sdk_r24.3.2-windows.zip
-sdk.win_bytes=187488291
-sdk.win_checksum=bcfe3c41ea7e33a29ad6f358adbdf977008be80a
+sdk.win_download=android-sdk_r24.3.3-windows.zip
+sdk.win_bytes=187480692
+sdk.win_checksum=b6a4899efbf20fc593042f1515446c6630ba502e
-sdk.win_installer=installer_r24.3.2-windows.exe
-sdk.win_installer_bytes=139471724
-sdk.win_installer_checksum=8f9d0ae9fdb37973ed62d6e93975ff375beb5542
+
+sdk.win_installer=installer_r24.3.3-windows.exe
+sdk.win_installer_bytes=139463749
+sdk.win_installer_checksum=bbdae40a7665e55b3cdb1fbae865986e6cd3df14
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 5559d1a..b89c068 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -7,6 +7,14 @@
@jd:body
+<p class="caution">
+ <strong>Important:</strong> Support for the Android Developer Tools (ADT) in Eclipse is ending,
+ per our <a href=
+ "http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio as soon as possible. For more information on transitioning to Android Studio, see
+ <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
<p>Android offers a custom plugin for the Eclipse IDE, called Android
Development Tools (ADT). This plugin provides a powerful, integrated
@@ -15,15 +23,6 @@
UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.
</p>
-<p class="note"><strong>Note:</strong>
-If you have been using Eclipse with ADT, be aware that <a
-href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
-for Android, so you should migrate to Android Studio to receive all the
-latest IDE updates. For help moving projects,
-see <a href="/sdk/installing/migrate.html">Migrating to Android
-Studio</a>.</p>
-
-
<p>You should install the ADT plugin
only if you already have an Eclipse installation that you want to continue using.
Your existing Eclipse installation must meet these requirements:</p>
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index 345e89a..d9829395 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -4,53 +4,264 @@
<div id="qv-wrapper">
<div id="qv">
+
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#overview">Migration Overview</a></li>
+ <li><a href="#prerequisites">Migration Prerequisites</a></li>
+ <li><a href="#migrate">Importing Projects to Android Studio</a></li>
+ <li><a href="#post-migration">Validating imported projects</a></li>
+</ol>
+
+
<h2>See also</h2>
<ul>
+ <li><a href="{@docRoot}tools/studio/eclipse-transition-guide.html">
+ Transition Guide for Eclipse ADT</a></li>
<li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
- class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
- <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Working+in+Eclipse+Compatibility+Mode" class="external-link"
- >Eclipse Compatibility Mode</a></li>
- <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA" class="external-link"
- >FAQ on Migrating</a></li>
+ class="external-link">IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+ <li><a href="http://confluence.jetbrains.com/display/IntelliJIDEA/IntelliJ+IDEA+for+Eclipse+Users"
+ class="external-link">IntelliJ IDEA for Eclipse users</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a></li>
</ul>
</div>
</div>
-<p>If you have been using <a href="{@docRoot}tools/help/adt.html">Eclipse with ADT</a>, be aware
-that <a href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE for
-Android, so you should migrate to Android Studio to receive all the latest IDE updates.</p>
+<p>Migrating from Eclipse ADT to Android Studio requires adapting to a new project structure,
+build system, and IDE functionality. To simplify the migration process, Android Studio provides an
+import tool so you can quickly transition your Eclipse ADT workspaces and Ant build scripts to
+Android Studio projects and <a href="http://www.gradle.org">Gradle</a>-based build files.</p>
-<p>To migrate existing Android projects, simply import them using Android Studio:</p>
+<p>This document provides an overview of the migration process and walks you
+through a sample import procedure. For more information about Android Studio features and the
+Gradle-based build system, see <a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a>
+and <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
+
+
+
+<h2 id="overview">Migration Overview </h2>
+<p>Migrating from Eclipse to Android Studio requires that you change the structure of your
+development projects, move to a new build system, and use a new user interface. Here are some of
+the key changes you should be aware of as you prepare to migrate to Android Studio:</p>
+<ul>
+ <li><strong>Project files</strong>
+ <p>Android Studio uses a different project structure. Each Eclipse ADT
+ project is called a module in Android Studio. Each instance of Android
+ Studio contains a project with one or more app modules. For more information see,
+ <a href="{@docRoot}tools/studio/eclipse-migration-guide.html#project-structure">Project
+ Structure</a>.</p></li>
+
+ <li><strong>Manifest settings</strong>
+ <p>Several elements in the <code>AndroidManifest.xml</code> file are now properties in the
+ <code>defaultConfig</code> and <code>productFlavors</code> blocks in the
+ <code>build.gradle</code> file. These elements are still valid manifest entries and may
+ appear in manifests from older projects, imported projects, dependencies, and libraries. For
+ more information see,
+ <a href="{@docRoot}tools/studio/eclipse-migration-guide.html#manifest-settings">Manifest
+ Settings</a>.</p></li>
+
+ <li><strong>Dependencies</strong>
+ <p>Library dependencies are handled differently in Android Studio, using Gradle dependency
+ declarations and Maven dependencies for well-known local source and binary libraries with
+ Maven coordinates. For more information see,
+ <a href="{@docRoot}tools/studio/eclipse-migration-guide.html#dependencies">Dependencies</a></p>
+ </li>
+
+ <li><strong>Test code</strong>
+ <p>With Eclipse ADT, test code is written in separate projects and integrated through the
+ <code><instrumentation></code> element in your manifest file. Android Studio provides a
+ <code>AndroidTest</code> folder within your project so you can easily add and maintain your test
+ code within the same project view. JUnit tests can also be configured to run locally to reduce
+ testing cycles.</p></li>
+
+ <li><strong>Gradle-based build system</strong>
+ <p>In place of XML-based Ant build files, Android Studio supports Gradle build files, which
+ use the Gradle Domain Specific Language (DSL) for ease of extensibility and customization.
+ The Android Studio build system also supports
+ <a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>,
+ which are combinations of <code>productFlavor</code> and <code>buildTypes</code>, to customize
+ your build outputs.</p></li>
+
+ <li><strong>User interface</strong>
+ <p>Android Studio provides an intuitive interface and menu options based on the
+ <a class="external-link" href="https://www.jetbrains.com/idea/" target="_blank">IntelliJ IDEA</a>
+ IDE. To become familiar with the IDE basics, such as navigation, code completion, and keyboard
+ shortcuts, see
+ <a class="external-link" href="https://www.jetbrains.com/idea/help/intellij-idea-quick-start-guide.html"
+ target="_blank">IntelliJ IDEA Quick Start Guide</a>.</p></li>
+
+ <li><strong>Developer tools versioning</strong>
+ <p>Android Studio updates independently of the Gradle-based build system so different build
+ settings can be applied across different versions of command line, Android Studio, and
+ continuous integration builds. For more information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
+ </li>
+</ul>
+
+
+
+
+<h2 id="prerequisites">Migration Prerequisites</h2>
+<p>Before migrating your Eclipse ADT app to Android Studio, review the following steps to make
+sure your project is ready for conversion, and verify you have the tool configuration you need in
+Android Studio:</p>
+
+<ul>
+ <li>In Eclipse ADT:
+ <ul>
+ <li>Make sure the Eclipse ADT root directory contains the <code>AndroidManifest.xml</code>
+ file. Also, the root directory must contain either the <code>.project</code> and
+ <code>.classpath</code> files from Eclipse or the <code>res/</code> and <code>src/</code>
+ directories.</li>
+ <li>Build your project to ensure your latest workspace and project updates are saved and
+ included in the import.</li>
+ <li>Comment out any references to Eclipse ADT workspace library files in the
+ <code>project.properties</code> or <code>.classpath</code> files for import. You can
+ add these references in the <code>build.gradle</code> file after the import. For more
+ information, see
+ <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</li>
+ <li>It may be useful to record your workspace directory, path variables, and any actual path
+ maps that could be used to specify any unresolved relative paths, path variables, and
+ linked resource references. Android Studio allows you to manually specify any unresolved
+ paths during the import process.</li>
+ </ul>
+ </li>
+ <li>In Android Studio:
+ <ul>
+ <li>Make a note of any third-party Eclipse ADT plugins in use and check for equivalent features
+ in Android Studio or search for a compatible plugin in the
+ <a href="https://plugins.jetbrains.com/?androidstudio" class="external-link">IntelliJ Android
+ Studio Plugins</a> repository. Use the <strong>File > Settings > Plugins</strong> menu
+ option to manage plugins in Android Studio. Android Studio does not migrate any third-party
+ Eclipse ADT plugins.</li>
+ <li>If you plan to run Android Studio behind a firewall, be sure to set the proxy settings for
+ Android Studio and the SDK Manager. Android Studio requires an internet connection for
+ Setup Wizard synchronization, 3rd-party library access, access to remote repositories,
+ <a href="http://www.gradle.org" class="external-link">Gradle</a>
+ initialization and synchronization, and Android Studio version updates. For more information,
+ see <a href="{@docRoot}tools/studio/index.html#proxy">Proxy Settings</a>.</li>
+ <li>Use the <strong>File > Settings > System Settings</strong> menu option to verify the
+ current version and, if necessary, update Android Studio to the latest version from the
+ stable channel. To install Android Studio, please visit the
+ <a href="{@docRoot}sdk/index.html">Android Studio download page</a>.</li>
+ </ul>
+ </li>
+ </ul>
+
+
+
+<h2 id="migrate">Importing Projects to Android Studio</h2>
+<p>Android Studio provides a function for importing Eclipse ADT projects, which creates a new
+Android Studio project and app modules based on your current
+Eclipse ADT workspace and projects. No changes are made to your Eclipse project files. The Eclipse
+ADT workspace becomes a new Android Studio project, and each Eclipse ADT project within the workspace
+becomes a new Android Studio module. Each instance of Android Studio contains a project with one or
+more app modules.</p>
+
+<p>After selecting an Eclipse ADT project to import, Android Studio creates the Android
+Studio project structure and app modules, generates the new Gradle-based build files and settings,
+and configures the required dependencies. The import options also allow you to enter your workspace
+directory and any actual path maps to handle any unresolved relative paths, path variables, and
+linked resource references.</p>
+
+<p>Depending on the structure of your Eclipse ADT development project, you should select specific
+files for importing:</p>
+<ul>
+<li>For workspaces with multiple projects, select the project folder for each Eclipse ADT
+ project individually to import the projects into the same Android Studio project. Android
+ Studio combines the Eclipse ADT projects into a single Android Studio project with different app
+ modules for each imported project.</li>
+
+<li>For Eclipse ADT projects with separate test projects, select the test project folder for
+ import. Android Studio imports the test project and then follows the dependency chain to import
+ the source project and any project dependencies.</li>
+
+ <li>If Eclipse ADT projects share dependencies within the same workspace, import each
+ project individually into Android Studio. Android Studio maintains the shared dependencies
+ across the newly created modules as part of the import process.</li>
+</ul>
+
+<p>To import a project to Android Studio:</p>
<ol>
- <li>In Android Studio, from the main menu or the <strong>Welcome to Android Studio</strong> page,
- choose <strong>File > Import Project</strong>.</li>
- <li> Select the Eclipse root project directory</strong> and click <strong>OK</strong>.
- <p class="note"><strong>Note:</strong> The Eclipse root directory must contain the
- <code>AndroidManifest.xml</code> file. Also, the root directory must contain either the
- <code>.project</code> and <strong>.classpath</strong> files from Eclipse or the
- <code>res/</code> and <code>src/</code> directories.</p>
- </li>
- <li>Follow the steps in the import wizard. </li>
+ <li>Start Android Studio and close any open Android Studio projects.</li>
+ <li>From the Android Studio menu select <strong>File > New > Import Project</strong>.
+ <p>Alternatively, from the <em>Welcome</em> screen, select <strong>Import project
+ (Eclipse ADT, Gradle, etc.)</strong>.</p></li>
+ <li>Select the Eclipse ADT project folder with the <code>AndroidManifest.xml</code> file
+ and click <strong>Ok</strong>.
+ <p> <img src="{@docRoot}images/tools/studio-select-project-forimport.png" alt="" /></p>
+ </li>
+ <li>Select the destination folder and click <strong>Next</strong>.
+ <p> <img src="{@docRoot}images/tools/studio-import-destination-dir.png" alt="" /></p></li>
+ <li>Select the import options and click <strong>Finish</strong>.
+ <p>The import process prompts to migrate any library and project dependencies to Android Studio,
+ and add the dependency declarations to the <code>build.gradle</code> file. The import process
+ also replaces any well-known source libraries, binary libraries, and JAR files that have known
+ Maven coordinates with Maven dependencies, so you no longer need to maintain these dependencies
+ manually. The import options also allow you to enter your workspace directory and any actual
+ path maps to handle any unresolved relative paths, path variables, and linked resource
+ references.</p>
+ <p> <img src="{@docRoot}images/tools/studio-import-options.png" alt="" /></p></li>
+
+ <li>Android Studio imports the app and displays the project import summary. Review the summary
+ for details about the project restructuring and the import process.
+ <p> <img src="{@docRoot}images/tools/studio-import-summary.png"/></p>
+ </li>
</ol>
-<p>Android Studio imports the current dependencies, downloads libraries, and
-creates an Android Studio project with the imported Eclipse project as the main module. Android
-Studio also creates the required Gradle build files. </p>
-
-<p>The import process replaces any JAR files and libraries with Gradle dependencies, and replaces
-source libraries and binary libraries with Maven dependencies, so you no longer need to maintain
-these files manually.</p>
-
- <p class="note"><strong>Note:</strong> If there are references to Eclipse workspace library files,
- comment them out in the <code>project.properties</code> or <code>.classpath</code> files
- that you imported from the Eclipse project. You can then add these files in the
- <code>build.gradle</code> file. See
- <a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+<p>After importing the project from Eclipse ADT to the new Android Studio project and module
+structure, each app module folder in Android Studio contains the complete source set for that
+module, including the {@code src/main} and {@code src/androidTest} directories, resources, build
+file, and Android manifest. Before starting app development, you should resolve any issues shown in
+the project import summary to make sure the project re-structuring and import process completed
+properly.</p>
-<p>For more help getting started with Android Studio and the IntelliJ user experience,
-<a href="{@docRoot}tools/studio/index.html">learn more about Android Studio</a> and
-read <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA"
- class="external-link">FAQ on Migrating to IntelliJ IDEA</a>.</p>
+
+<h3 id="post-migration">Validating imported projects</h3>
+<p>After completing the import process, use the Android Studio <strong>Build</strong> and
+<strong>Run</strong> menu options to build your project and verify the output. If your project
+is not building properly, check the following settings:</p>
+
+<ul>
+<ul>
+ <li>Use the <strong>Android SDK</strong> button in Android Studio to launch the <a href=
+ "{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> and verify the installed versions of SDK
+ tools, build tools, and platform match the settings for your Eclipse ADT project. Android Studio
+ inherits the SDK Manager and JDK settings from your imported Eclipse project.
+ </li>
+ <li>Use the <strong>File > Project Structure</strong> menu option to verify additional
+ Android Studio settings:
+ <ul>
+ <li>Under <em>SDK Location</em> verify Android Studio has access to the correct SDK and
+ JDK locations and versions. </li>
+ <li>Under <em>Project</em> verify the Gradle version, Android Plugin version, and related
+ repositories.</li>
+ <li>Under <em>Modules</em> verify the app and module settings, such as signing configuration
+ and library dependencies. </li>
+ </ul>
+ </li>
+ <li>If your project depends on another project, make sure that dependency is defined properly in
+ the <code>build.gradle</code> file in the app module folder.</li>
+</ul>
+
+
+<p>If there still are unexpected issues when building and running your project in Android
+Studio after you have checked these settings, consider modifying the Eclipse ADT project and
+re-starting the import process. Importing an Eclipse ADT project to Android Studio creates a new
+Android Studio project and does not impact the existing Eclipse ADT project. </p>
+
+
+
+<p>To get started using Android Studio, review the
+<a href="{@docRoot}tools/studio/index.html">Android Studio</a> features and
+<a href="http://www.gradle.org">Gradle</a>-based build system to become familiar with the new
+project and module structure, flexible build settings, and other advanced Android development
+capabilities. For a comparison of Eclipse ADT and Android Studio features and usage, see
+<a href="{@docRoot}tools/studio/eclipse-migration-guide.html">Transitioning to Android Studio from
+Eclipse</a>. For specific Android Studio how-to documentation, see the pages in the
+<a href="{@docRoot}tools/workflow/index.html">Workflow</a> section.
+</p>
diff --git a/docs/html/support.jd b/docs/html/support.jd
index bbed7df..94d6478 100644
--- a/docs/html/support.jd
+++ b/docs/html/support.jd
@@ -8,80 +8,96 @@
<div class="wrap" style="width:940px;">
- <h1>Developer Support Resources</h1>
-<!--
-<p>A variety of support resources are available to help you report and resolve issues while you are developing apps for Android. </p>
--->
- <div style="margin: 20px 0 0;">
+<h1>Developer Support Resources</h1>
- <div class="col-8" style="margin-left:0">
- <h3 style="font-size: 14px;line-height: 21px;color: #555;text-transform: uppercase;border-bottom: 1px solid #CCC;margin: 0 0 20px;">Code-Level Support</h3>
-
-<h5>Community and Office Hours</h5>
-<p style="color:#888">
+<div style="margin: 20px 0 0;">
-<a href="https://plus.google.com/+AndroidDevelopers">Android Developers</a> on Google+<br />
-<a href="https://plus.google.com/communities/105153134372062985968">Android Development community</a> on Google+<br />
-<a href="http://groups.google.com/group/android-developers">android-developers</a> support forum<br />
-<a href="http://groups.google.com/group/android-ndk">android-ndk</a> support forum<br />
-<a href="http://groups.google.com/group/android-security-discuss">android-security-discuss</a> support forum<br />
+<div class="col-8" style="margin-left:0">
- <a href="http://webchat.freenode.net/?channels=android">#android</a>, <a href="http://webchat.freenode.net/?channels=android-dev">#android-dev</a> <span style="color:#888">(IRC via irc.freenode.net)</span><br />
-</p>
+ <h3 style="font-size: 14px;line-height: 21px;color: #555;text-transform:
+ uppercase;border-bottom: 1px solid #CCC;margin: 0 0 20px;">
+ Code-Level Support</h3>
-<p><b>
-<a target="_blank"
-href="https://helpouts.google.com/partner/ask?vertical=programming&tags=android&origin=http:%2F%2Fdeveloper.android.com%2Fsupport.html">Ask a question in Google Helpouts</a>
-</b></p>
+ <h5>Community Resources</h5>
+ <p style="color:#888">
+
+ <a href="https://plus.google.com/+AndroidDevelopers">
+ Android Developers</a> on Google+<br />
+ <a href="https://plus.google.com/communities/105153134372062985968">
+ Android Development community</a> on Google+<br />
+ <a href="http://groups.google.com/group/android-developers">
+ android-developers</a> support forum<br />
+ <a href="http://groups.google.com/group/android-ndk">
+ android-ndk</a> support forum<br />
+ <a href="http://groups.google.com/group/android-security-discuss">
+ android-security-discuss</a> support forum<br />
+
+ <a href="http://webchat.freenode.net/?channels=android">#android</a>,
+ <a href="http://webchat.freenode.net/?channels=android-dev">#android-dev</a>
+ <span style="color:#888">(IRC via irc.freenode.net)</span><br />
+ </p>
-<h5>Send Feedback</h5>
-<p>
- <a href="http://code.google.com/p/android/issues/entry?template=Developer%20Documentation">Report documentation bug</a><br />
- <a href="https://code.google.com/p/android/issues/entry?template=User%20bug%20report">Report device bug</a><br />
- <a href="https://code.google.com/p/android/issues/entry?template=Developer%20bug%20report">Report platform bug</a><br />
-</p>
-
-
- </div>
-
-
-
- <div class="col-8" style="margin-right:0">
- <h3 style="font-size: 14px;line-height: 21px;color: #555;text-transform:
-uppercase;border-bottom: 1px solid #CCC;margin: 0 0 20px;">Google Play Support</h3>
-<h5>Help center</h5>
-<p style="color:#888">
- <a href="http://support.google.com/googleplay/android-developer/">Help Center Home</a><br />
- <a href="http://support.google.com/googleplay/android-developer/bin/static.py?hl=en&page=known_issues.cs">Known Issues</a><br />
-</p>
-
-<h5 id="contact">Direct support contacts for developers</h5>
-<p style="color:#888">
- <a href=" https://support.google.com/googleplay/android-developer/troubleshooter/3049653">Registration, account issues</a><br />
- <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3055196">Publishing, app distribution issues</a><br />
- <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3055329">App visibility and discoverability</a><br />
- <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3076003">Billing and reporting</a><br />
- <a href="http://support.google.com/googleplay/android-developer/bin/request.py?contact_type=takedown">Inappropriate apps</a><br />
- <a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=1085703&topic=15868&ctx=topic">Report a Google Play policy violation</a>
-</p>
-
-<h5>End-user support</h5>
-<p style="color:#888">
- <a href="http://support.google.com/googleplay/bin/request.py?contact_type=contact_policy&policy=apps">Click-to-call and email support for Google Play end users</a><br />
-</p>
-
-
-
- <h5>Payment and Merchant Issues</h5>
-
-<p style="color:#888;margin-bottom:1.5em;">
- <a href="http://support.google.com/checkout/sell/">Merchant Help Center Home<br />
- <a href="http://support.google.com/checkout/sell/bin/static.py?hl=en&page=ts.cs&ts=2472700">Issue reporting tool<br />
- <a href="https://productforums.google.com/forum/#!forum/checkout-merchant">checkout-merchant</a> support forum<br />
- <a href="http://support.google.com/googleplay/android-developer/bin/request.py?contact_type=survey">Feedback survey</a>
-</p>
+ <h5>Send Feedback</h5>
+ <p>
+ <a href="http://code.google.com/p/android/issues/entry?template=Developer%20Documentation">
+ Report documentation bug</a><br />
+ <a href="https://code.google.com/p/android/issues/entry?template=User%20bug%20report">
+ Report device bug</a><br />
+ <a href="https://code.google.com/p/android/issues/entry?template=Developer%20bug%20report">
+ Report platform bug</a><br />
+ </p>
</div>
+
+
+
+<div class="col-8" style="margin-right:0">
+ <h3 style="font-size: 14px;line-height: 21px;color: #555;text-transform:
+ uppercase;border-bottom: 1px solid #CCC;margin: 0 0 20px;">
+ Google Play Support</h3>
+
+ <h5>Help center</h5>
+ <p>
+ <a href="http://support.google.com/googleplay/android-developer/">Help Center Home</a><br />
+ </p>
+
+ <h5 id="contact">Direct support contacts for developers</h5>
+ <p>
+ <a href=" https://support.google.com/googleplay/android-developer/troubleshooter/3049653">
+ Registration, account issues</a><br />
+ <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3055196">
+ Publishing, app distribution issues</a><br />
+ <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3055329">
+ App visibility and discoverability</a><br />
+ <a href="https://support.google.com/googleplay/android-developer/troubleshooter/3076003">
+ Billing and reporting</a><br />
+ <a href="http://support.google.com/googleplay/android-developer/bin/request.py?contact_type=takedown">
+ Inappropriate apps</a><br />
+ <a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=1085703&topic=15868&ctx=topic">
+ Report a Google Play policy violation</a>
+ </p>
+
+ <h5>End-user support</h5>
+ <p>
+ <a href="http://support.google.com/googleplay/bin/request.py?contact_type=contact_policy&policy=apps">
+ Support for Google Play end users</a><br />
+ </p>
+
+
+
+ <h5>Payment and Merchant Issues</h5>
+
+ <p style="margin-bottom:1.5em;">
+ <a href="http://support.google.com/checkout/sell/">
+ Merchant Help Center Home<br />
+ <a href="http://support.google.com/googleplay/android-developer/bin/request.py?contact_type=survey">
+ Feedback survey</a>
+ </p>
+
+
</div>
+
+</div> <!-- end margin: 20px -->
+</div> <!-- end class:wrap -->
diff --git a/docs/html/tools/building/building-cmdline-ant.jd b/docs/html/tools/building/building-cmdline-ant.jd
index 51158de..add6ca2 100644
--- a/docs/html/tools/building/building-cmdline-ant.jd
+++ b/docs/html/tools/building/building-cmdline-ant.jd
@@ -31,6 +31,14 @@
</div>
</div>
+<p class="caution">
+ <strong>Important:</strong> Support for Ant as a build tool for Android is ending, per our
+ <a href="http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio and Gradle as soon as possible. For more information on transitioning to these
+ tools, see <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
+
<p>There are two ways to build your application using the Ant build script: one for
testing/debugging your application — <em>debug mode</em> — and one for building your
final package for release — <em>release mode</em>. Regardless of which way you build your application,
diff --git a/docs/html/tools/building/building-cmdline.jd b/docs/html/tools/building/building-cmdline.jd
index 0e4c8b2..bf3e873 100644
--- a/docs/html/tools/building/building-cmdline.jd
+++ b/docs/html/tools/building/building-cmdline.jd
@@ -353,13 +353,6 @@
to publish your application, you <strong>must</strong> sign the application with your own private
key, rather than the debug key generated by the SDK tools.</p>
- <p>Android Studio helps you get started quickly by signing your .apk files with a debug key,
- prior to installing them on an emulator or development device. This means that you can quickly
- run your application from Android Studio without having to generate your own private key. No
- specific action on your part is needed, provided ADT has access to Keytool. However, please note
- that if you intend to publish your application, you <strong>must</strong> sign the application
- with your own private key, rather than the debug key generated by the SDK tools.</p>
-
<p>Please read <a href="{@docRoot}tools/publishing/app-signing.html">Signing Your
Applications</a>, which provides a thorough guide to application signing on Android and what it
means to you as an Android application developer. The document also includes a guide to publishing
diff --git a/docs/html/tools/building/manifest-merge.jd b/docs/html/tools/building/manifest-merge.jd
new file mode 100644
index 0000000..54166ec
--- /dev/null
+++ b/docs/html/tools/building/manifest-merge.jd
@@ -0,0 +1,510 @@
+page.title=Manifest Merging
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#merge-rules">Merge Conflict Rules</a></li>
+ <li><a href="#markers-selectors">Merge Conflict Markers and Selectors</a></li>
+ <li><a href="#inject-values">Injecting Build Values into a Manifest</a></li>
+ <li><a href="#merge-prodflavorsGroups">Manifest Merging Across Product Flavor Groups</a></li>
+ <li><a href="#implicit-permissions">Implicit Permissions</a></li>
+ <li><a href="#merge-errors">Handling Manifest Merge Build Errors</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a></li>
+ <li><a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a> </li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>With Android Studio and <a href="http://www.gradle.org">Gradle</a>-based builds, each app can
+contain manifest files in multiple locations, such as the <code>src/main/</code> folder for
+the <code>productFlavor</code>, libraries, Android ARchive (AAR) bundles of Android Library
+projects, and dependencies. During the build process, manifest merging combines the settings from
+the various <code>AndroidManifest.xml</code> files included in your app into a single, generated APK
+manifest file for app packaging and distribution. Manifest settings are merged based on the manifest
+priority, determined by the manifest's file location. Building your app merges the
+manifest elements, attributes, and sub-elements from these manifests for the specified
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">build variant</a>.</p>
+
+
+<h2 id="merge-rules">Merge Conflict Rules</h2>
+<p>Merge conflicts occur when merged manifests contain the same manifest element but with a
+different attribute value that does not resolve based on the default merge conflict rules.
+<a href="#markers-selectors">Conflict markers and selectors</a> can also define custom merge rules,
+such as allowing an imported library to have a <code>minSdkVersion</code> higher than the
+version defined in the other higher priority manifests. </p>
+
+<p>The manifest merge priority determines which manifest settings are retained in merge conflicts,
+with the settings in higher priority manifest overwriting those in lower priority manifests.
+The following list details which manifest settings are are the highest priority during the merge
+process:</p>
+
+<ul>
+ <li>Highest priority: <code>buildType</code> manifest settings </li>
+ <li>Higher priority: <code>productFlavor</code> manifest settings </li>
+ <li>Medium priority: Manifests in the <code>src/main/</code> directory of an app project</li>
+ <li>Low priority: Dependency and library manifest settings </li>
+</ul>
+
+<p>Manifest merge conflicts are resolved at the XML node and
+attribute levels based on the following merge rules. </p>
+
+<table>
+ <tr>
+ <th scope="col">High Priority Element</th>
+ <th scope="col">Low Priority Element</th>
+ <th scope="col">Manifest Merge Result</th>
+ </tr>
+ <tr>
+ <td rowspan="3">no attribute</td>
+ <td>no attribute</td>
+ <td>no attribute</td>
+ </tr>
+ <tr>
+
+ <td>attribute set to default</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+
+ <td>attribute set to non-default </td>
+ <td>low priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td rowspan="2">no attribute</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default </td>
+
+ <td>high priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td>attribute set to default</td>
+ <td>default attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to default</td>
+ <td>attribute set to non-default </td>
+ <td>low priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default</td>
+ <td>attribute set to default</td>
+ <td>high priority attribute</td>
+ </tr>
+ <tr>
+ <td>attribute set to non-default</td>
+ <td>attribute set to non-default </td>
+ <td>Merge if settings match, otherwise causes conflict error.</td>
+ </tr>
+ </table>
+
+
+
+<p>Exceptions to the manifest merge rules: </p>
+
+<ul>
+ <li>The <code>uses-feature android:required;</code> and
+ <code>uses-library android:required</code> elements default to <code>true</code> and use
+ an <em>OR</em> merge so that any required feature or library is included in the generated APK. </li>
+
+ <li>If not declared, the
+ <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+ elements, <code>minSdkVersion</code> and
+ <code>targetSdkVersion</code>, default to a value of 1. When
+ merge conflicts occur, the value in the higher priority manifest version is used.</li>
+
+ <li>Importing a library with a <code>minSdkVersion</code> value higher than the app's
+ <code>src/main/</code> manifest manifest generates an error unless
+ the <code>overrideLibrary</code> conflict marker is used.
+
+ <p class="note"><strong>Note:</strong> If not explicitly declared, the <code>targetSdkVersion</code>
+ defaults to the <code>minSdkVersion</code> value. When no <code><uses-sdk></code> element is
+ present in any manifest or the <code>build.gradle</code> file, the
+ <code>minSdkVersion</code> defaults to 1.</p> </li>
+
+ <li>When importing a library with a <code>targetSdkVersion</code> value lower than the app's
+ <code>src/main/</code> manifest, the manifest merge
+ process explicitly grants permissions and ensures that the imported library functions properly. </li>
+
+ <li>The <code>manifest</code> element only merges with child manifest elements. </li>
+
+ <li>The <code>intent-filter</code> element is never changed and is always added to the common
+ parent node in the merged manifest. </li>
+</ul>
+
+<p class="caution"><strong>Important:</strong> After the manifests are merged, the build process
+overrides the final manifest settings with any settings that are also in the
+<code>build.gradle</code> file. For more details, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+
+<h2 id="markers-selectors">Merge Conflict Markers and Selectors</h2>
+<p>Manifest markers and selectors override the default merge rules through
+specific conflict resolutions. For example, use a conflict marker to
+merge a library manifest with a higher <code>minSdkVersion</code> value than the higher priority
+manifest, or to merge manifests with the same activity but different <code>android:theme</code>
+values. </p>
+
+<h3 id="conflict-markers">Merge Conflict Markers</h3>
+<p>A merge conflict marker is a special attribute in the Android tools namespace that defines a
+specific merge conflict resolution. Create a conflict marker to avoid a merge conflict error for
+conflicts not resolved by the default merge rules. Supported merge conflict markers include:</p>
+
+<dl>
+ <dt><code>merge</code></dt>
+ <dd>Merges attributes when there are no conflicts with the merge rules. The default merge
+ action.</dd>
+ <dt><code>replace</code></dt>
+ <dd>Replaces attributes in the lower priority manifest with those from the higher priority
+ manifest.</dd>
+ <dt><code>strict</code></dt>
+ <dd>Sets the merge policy level so that merged elements with same attributes, but different
+ values generate a build failure, unless resolved through the conflict rules.</dd>
+ <dt><code>merge-only</code></dt>
+ <dd>Allows merge actions for only lower priority attributes.</dd>
+ <dt><code>remove</code></dt>
+ <dd>Removes the specified lower priority element from the merged manifest.</dd>
+ <dt><code>remove-All</code></dt>
+ <dd>Removes all lower priority elements of the same node type from the merged manifest.</dd>
+</dl>
+
+
+<p>By default, the manifest merge process applies the <code>merge</code> conflict marker to
+the node level. All declared manifest attributes default to a <code>strict</code>
+merging policy. </p>
+
+<p>To set a merge conflict marker, first declare the namespace in the
+<code>AndroidManifest.xml</code> file. Then, enter the merge conflict marker in the manifest to
+specify a custom merge conflict action. This example inserts the <code>replace</code> marker to
+set a replace action to resolve conflicts between the <code>android:icon</code> and
+<code>android:label</code> manifest elements. </p>
+
+<pre>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.tests.flavorlib.app"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <application
+ android:icon="@drawable/icon"
+ android:label="@string/app_name"
+ tools:replace="icon, label">
+ ...
+
+</manifest>
+
+</pre>
+
+
+<h4>Marker attributes</h4>
+<p>Conflict markers use <code>tools:node</code> and <code>tools:attr</code> attributes to
+restrict merge actions at the XML node or attribute level. </p>
+
+<p>The <code>tools:attr</code> markers use only the <code>restrict</code>, <code>remove</code>, and
+<code>replace</code> merge actions. Multiple <code>tools:attr</code> marker values can be applied
+to a specific element. For example, use <code>tools:replace="icon, label, theme"</code> to replace
+lower priority <code>icon</code>, <code>label</code>, and <code>theme</code> attributes. </p>
+
+
+<h4>Merge conflict marker for imported libraries</h4>
+<p>The <code>overrideLibrary</code> conflict marker applies to the <code><uses-sdk></code>
+manifest declaration and is used to import a library even though the library's
+<code><uses-sdk></code> values, such as <code>minSdkVersion</code>
+are set to different values than those in the other higher priority manifests. </p>
+
+<p>Without this marker, library manifest merge conflicts from the
+<code><uses-sdk></code> values cause the merge process to fail.</p>
+
+<p>This example applies the <code>overrideLibrary</code> conflict marker to resolve the merge
+conflict between <code>minSdkVersion</code> values in the <code>src/main/</code> manifest and an
+imported library manifest.
+
+
+<p><code>src/main/</code> manifest: </p>
+<pre>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.example.app"
+ xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <uses-sdk android:targetSdkVersion="22" android:minSdkVersion="2"
+ tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
+ ...
+</pre>
+
+<p>Library manifest: </p>
+
+<pre>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+ ...
+ <uses-sdk android:minSdkVersion="4" />
+ ...
+ </manifest>
+</pre>
+
+<p class="note"><strong>Note:</strong> The default merge process does not allow importing a library
+with a higher <code>minSdkVersion</code> than the app's <code>src/main/</code> manifest unless
+the <code>overrideLibrary</code> conflict marker is used. </p>
+
+
+
+<h3 id="marker-selectors">Marker Selectors</h3>
+<p>Marker selectors limit a merge action to a specific lower priority manifest. For example, a
+marker selector can be used to remove a permission from only one library, while allowing the
+same permission from other libraries.</p>
+
+<p>This example uses the <code>tools:node</code> marker to remove the <code>permisionOne</code>
+attribute, while the <code>tools:selector</code> selector specifies the specific library as
+<em>com.example.lib1</em>. The <code>permisionOne</code> permission is filtered from only the
+<code>lib1</code> library manifests. </p>
+
+<pre>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.example.app"
+ xmlns:tools="http://schemas.android.com/tools">
+ ...
+ <permission
+ android:name="permissionOne"
+ tools:node="remove"
+ tools:selector="com.example.lib1">
+ ...
+</pre>
+
+
+
+<h2 id="inject-values">Injecting Build Values into a Manifest</h2>
+<p>Manifest merging can also be configured to use manifest placeholders to inject
+property values from the <code>build.gradle</code> file into the manifest attributes. </p>
+
+<p>Manifest placeholders use the syntax <code>${name}</code> for attribute values, where
+<code>name</code> is the injected <code>build.gradle</code> property. The <code>build.gradle</code>
+file uses the <code>manifestPlaceholders</code> property to define the placeholder values. </p>
+
+<p class="note"><strong>Note:</strong> Unresolved placeholder names in apps cause build failures.
+Unresolved placeholder names in libraries generate warnings and need to be resolved when importing
+the library into an app.</p>
+
+<p>This example shows the manifest placeholder <code>${applicationId}</code> used to inject the
+<code>build.gradle</code> <code>applicationId</code> property value in to <code>android:name</code>
+attribute value. </p>
+
+<p class="note"><strong>Note:</strong> Android Studio provides a default
+<code>${applicationId}</code> placeholder for the <code>build.gradle</code>
+<code>applicationId</code> value that is not shown in the build file.</p>
+
+
+<p>Manifest entry:</p>
+
+<pre>
+
+<activity
+android:name=".Main">
+ <intent-filter>
+ <action android:name="${applicationId}.foo">
+ </action>
+</intent-filter>
+</activity>
+
+</pre>
+
+
+<p>Gradle build file:</p>
+
+<pre>
+android {
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
+
+ productFlavors {
+ flavor1 {
+ applicationId = "com.mycompany.myapplication.productFlavor1"
+ }
+}
+
+</pre>
+
+<p>Merged manifest value: </p>
+
+<pre>
+<action android:name="com.mycompany.myapplication.productFlavor1.foo">
+</pre>
+
+
+<p>The manifest placeholder syntax and build file <code>manifestPlaceholders</code>
+property can be used to inject other manifest values. For properties other than the
+<code>applicationId</code>, the <code>manifestPlaceholders</code> property is explicitly declared
+in the <code>build.gradle</code> file. This example shows the manifest placeholder for injecting
+<code>activityLabel</code> values.</p>
+
+<p>Gradle build file: </p>
+
+<pre>
+android {
+ defaultConfig {
+ manifestPlaceholders = [ activityLabel:"defaultName"]
+ }
+ productFlavors {
+ free {
+ }
+ pro {
+ manifestPlaceholders = [ activityLabel:"proName" ]
+ }
+ }
+
+</pre>
+
+<p>Placeholder in the manifest file: </p>
+
+<pre>
+<activity android:name=".MainActivity" android:label="${activityLabel}" >
+</pre>
+
+<p class="note"><strong>Note:</strong> The placeholder value supports partial value injection,
+for example <code>android:authority="com.acme.${localApplicationId}.foo"</code>. </p>
+
+
+
+<h2 id="merge-prodflavorsGroups">Manifest Merging Across Product Flavor Groups</h2>
+
+<p>When using the <code>GroupableProductFlavor</code> property, the manifest merge
+priority of any manifests in the product flavor groups follows the order in which the
+product flavor groups are listed in the build file. The manifest merge process creates a single
+merged manifest for the product flavor groups based on the configured build variant. </p>
+
+<p>For example, if a build variant references the product flavors <code>x86</code>,
+<code>mdpi</code>, <code>21</code>, and <code>paid</code> from the respective product flavor
+groups <code>ABI</code>, <code>Density</code>, <code>API</code>, and <code>Prod</code>, listed
+in this order in the <code>build.gradle</code> file, then the manifest merge process merges the
+manifests in this priority order, which follows how the product flavors are listed in the build
+file.</p>
+
+<p>To illustrate this example, the following table shows how the product flavors are listed for
+each product flavor group. This combination of product flavors and groups defines the
+build variant. </p>
+<table>
+ <tr>
+ <th scope="col">Product Flavor Group</th>
+ <th scope="col">Product Flavor</th>
+ <tr>
+ <td>ABI</td>
+ <td>x86</td>
+ </tr>
+ <tr>
+ <td>density</td>
+ <td>mdpi</td>
+ </tr>
+ <tr>
+ <td>API</td>
+ <td>22</td>
+ </tr>
+ <tr>
+ <td>prod</td>
+ <td>paid</td>
+ </tr>
+</table>
+
+<p>Manifest merge order:</p>
+
+ <ul>
+ <li>prod-paid AndroidManifest.xml (lowest priority) merges into API-22 AndroidManifest.xml</li>
+ <li>API-22 AndroidManifest.xml merges into density-mpi AndroidManifest.xml</li>
+ <li>density-mpi AndroidManifest.xml merges into ABI-x86 AndroidManifest.xml (highest priority)</li>
+ </ul>
+
+
+<h2 id="implicit-permissions">Implicit Permissions</h2>
+<p>Importing a library that targets an Android runtime with implicitly
+granted permissions may automatically add the permissions to the resulting merged manifest.
+For example, if an application with a <code>targetSdkVersion</code> of 16 imports a library with a
+<code>targetSdkVersion</code> of 2, Android Studio adds the <code>WRITE_EXTERNAL_STORAGE</code>
+permission to ensure permission compatibility across the SDK versions.
+
+<p class="note"><strong>Note:</strong> More recent Android releases replace implicit
+permissions with permission declarations.</p>
+
+
+This table lists the importing library versions and the declared permissions.
+</p>
+
+ <table>
+ <tr>
+ <th>Importing this library version</th>
+ <th>Declares this permission in the manifest </th>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> < 2 </td>
+ <td><code>WRITE_EXTERNAL_STORAGE</code> </td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> < 4 </td>
+ <td><code>WRITE_EXTERNAL_STORAGE</code>, <code>READ_PHONE_STATE</code> </td>
+ </tr>
+ <tr>
+ <td>Declared <code>WRITE_EXTERNAL_STORAGE</code></td>
+ <td><code>READ_EXTERNAL_STORAGE</code></td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> < 16 and using the <code>READ_CONTACTS</code>
+ permission</td>
+ <td><code>READ_CALL_LOG</code></td>
+ </tr>
+ <tr>
+ <td><code>targetSdkVersion</code> < 16 and using the <code>WRITE_CONTACTS</code>
+ permission</td>
+ <td><code>WRITE_CALL_LOG</code></td>
+ </tr>
+ </table>
+
+
+
+<h2 id="merge-errors">Handling Manifest Merge Build Errors</h2>
+<p>During the build process, the manifest merge process stores a record of each merge transaction
+in the <code>manifest-merger-<productFlavor>-report.txt</code> file in the module
+<code>build/outputs/logs</code> folder. A different log file is generated for each of the
+module's build variants. </p>
+
+<p>When a manifest merge build error occurs, the merge process records the error message
+describing the merge conflict in the log file. For example, the
+<code>android:screenOrientation</code> merge conflict between the following manifests causes
+a build error. </p>
+
+<p>Higher priority manifest declaration: </p>
+
+<pre>
+<activity
+ android:name="com.foo.bar.ActivityOne"
+ android:screenOrientation="portrait"
+ android:theme="@theme1"/>
+</pre>
+
+<p>Lower priority manifest declaration: </p>
+
+<pre>
+<activity
+ android:name="com.foo.bar.ActivityOne"
+ android:screenOrientation="landscape"/>
+</pre>
+
+<p>Error log:</p>
+
+<pre>
+/project/app/src/main/AndroidManifest.xml:3:9 Error:
+ Attribute activity@screenOrientation value=(portrait) from AndroidManifest.xml:3:9
+ is also present at flavorlib:lib1:unspecified:3:18 value=(landscape)
+ Suggestion: add 'tools:replace="icon"' to <activity> element at AndroidManifest.xml:1:5 to override
+</pre>
+
+
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 41c6686..641d463 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -16,18 +16,7 @@
<li><a href="#move">Installing an Application</a></li>
<li><a href="#forwardports">Forwarding Ports</a></li>
<li><a href="#copyfiles">Copying Files to or from an Emulator/Device Instance</a></li>
- <li><a href="#shellcommands">Issuing Shell Commands</a>
- <ol>
- <li><a href="#am">Using activity manager (am)</a></li>
- <li><a href="#pm">Using package manager (pm)</a></li>
- <li><a href="#sqlite">Examining sqlite3 databases from a remote shell</a></li>
- <li><a href="#screenrecord">Recording a device screen</a></li>
- <li><a href="#monkey">UI/Application Exerciser Monkey</a></li>
- <li><a href="#othershellcommands">Other shell commands</a></li>
- </ol>
- </li>
- <li><a href="#logcat">Enabling logcat logging</a></li>
- <li><a href="#stopping">Stopping the adb server</a></li>
+ <li><a href="#stopping">Stopping the adb Server</a></li>
<li><a href="#wireless">Wireless usage</a></li>
</ol>
@@ -279,7 +268,7 @@
<td rowspan="2">Shell</td>
<td><code>shell</code></td>
<td>Starts a remote shell in the target emulator/device instance.</td>
-<td rowspan="2">See <a href="#shellcommands">Issuing Shell Commands</a> for more information. </td>
+<td rowspan="2">See <a href="{@docRoot}tools/help/shell.html#shellcommands">ADB Shell Commands</a> for more information. </td>
</tr>
<tr>
@@ -412,950 +401,10 @@
+<h2 id="stopping">Stopping the adb Server</h2>
-
-
-
-
-<h2 id="shellcommands">Issuing Shell Commands</h2>
-
-<p>Adb provides a Unix shell that you can use to run a variety of commands on an emulator
-or connected device. The command binaries are stored in the file system of the emulator or device,
-at <code>/system/bin/...</code>
-
-<p>Two of the most common command tools are <a href="#am">activity manager</a> ({@code am}) and
-<a href="#pm">package manager</a> ({@code pm}).</p>
-
-<p>You can use the <code>shell</code> command to issue commands, with or without entering
-the adb remote shell on the emulator/device. To issue a single command without entering a
-remote shell, use the <code>shell</code> command like this: </p>
-
- <pre class="no-pretty-print">adb [-d|-e|-s <serialNumber>] shell <shell_command></pre>
-
-<p>Or enter a remote shell on an emulator/device like this:</p>
-
- <pre class="no-pretty-print">adb [-d|-e|-s <serialNumber>] shell</pre>
-
-<p>When you are ready to exit the remote shell, press CTRL+D or type
-<code>exit</code>. </p>
-
-
-
-
-
-<h3 id="am">Using activity manager (am)</h3>
-
-<p>Within an adb shell, you can issue commands with the activity manager ({@code am}) tool to
-perform various system actions, such as start an activity, force-stop a process,
-broadcast an intent, modify the device screen properties, and more. While in a shell,
-the syntax is:</p>
-<pre class="no-pretty-print">
-am <command>
-</pre>
-
-<p>You can also issue an activity manager command directly from adb
-without entering a remote shell. For example:</p>
-<pre class="no-pretty-print">
-adb shell am start -a android.intent.action.VIEW
-</pre>
-
-
-<p class="table-caption"><strong>Table 2.</strong> Available activity manager commands</p>
-<table>
-<tr>
- <th>Command</th>
- <th>Description</th>
-</tr>
-
-<tr>
-<td><code>
-start [options] <INTENT>
-</code></td>
-<td>Start an {@link android.app.Activity} specified by {@code <INTENT>}. <p>See the
-<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
-<p>Options are:
-<ul>
- <li>{@code -D}: Enable debugging.
- <li>{@code -W}: Wait for launch to complete.
- <li>{@code --start-profiler <FILE>}: Start profiler and send results to {@code <FILE>}.
- <li>{@code -P <FILE>}: Like <code>--start-profiler</code>,
- but profiling stops when the app goes idle.
- <li>{@code -R}: Repeat the activity launch {@code <COUNT>} times. Prior to each repeat,
- the top activity will be finished.
- <li>{@code -S}: Force stop the target app before starting the activity.
- <li>{@code --opengl-trace}: Enable tracing of OpenGL functions.
- <li>{@code --user <USER_ID> | current}: Specify which user to run as; if not
- specified, then run as the current user.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-startservice [options] <INTENT>
-</code></td>
-<td>Start the {@link android.app.Service} specified by {@code <INTENT>}. <p>See the
-<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
-<p>Options are:
-<ul>
- <li>{@code --user <USER_ID> | current}: Specify which user to run as; if not
- specified, then run as the current user.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-force-stop <PACKAGE>
-</code></td>
-<td>Force stop everything associated with {@code <PACKAGE>} (the app's package name).
-</td>
-</tr>
-
-<tr>
-<td><code>
-kill [options] <PACKAGE>
-</code></td>
-<td> Kill all processes associated with {@code <PACKAGE>}
- (the app's package name). This command kills only
- processes that are safe to kill and that will not impact the user
- experience.
- <p>Options are:
- <ul>
- <li>{@code --user <USER_ID> | all | current}: Specify user whose processes to kill;
- all users if not specified.
- </ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-kill-all
-</code></td>
-<td>Kill all background processes.
-</td>
-</tr>
-
-<tr>
-<td><code>
-broadcast [options] <INTENT>
-</code></td>
-<td>Issue a broadcast intent. <p>See the
-<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
-<p>Options are:
-<ul>
- <li>{@code [--user <USER_ID> | all | current]}: Specify which user to send to; if not
- specified then send to all users.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-instrument [options] <COMPONENT>
-</code></td>
-<td>Start monitoring with an {@link android.app.Instrumentation} instance.
- Typically the target {@code <COMPONENT>}
- is the form {@code <TEST_PACKAGE>/<RUNNER_CLASS>}. <p>Options are:
-<ul>
- <li>{@code -r}: Print raw results (otherwise decode
- {@code <REPORT_KEY_STREAMRESULT>}). Use with
- {@code [-e perf true]} to generate raw output for performance measurements.
-
- <li>{@code -e <NAME> <VALUE>}: Set argument {@code <NAME>} to {@code <VALUE>}.
- For test runners a common form is {@code
- -e <testrunner_flag> <value>[,<value>...]}.
-
- <li>{@code -p <FILE>}: Write profiling data to {@code <FILE>}.
-
- <li>{@code -w}: Wait for instrumentation to finish before returning. Required for
- test runners.
-
- <li>{@code --no-window-animation}: Turn off window animations while running.
- <li>{@code --user <USER_ID> | current}: Specify which user instrumentation runs in;
- current user if not specified.
-</ul>
-
-</td>
-</tr>
-
-<tr>
-<td><code>
-profile start <PROCESS> <FILE>
-</code></td>
-<td>Start profiler on {@code <PROCESS>}, write results to {@code <FILE>}.
-</td>
-</tr>
-
-<tr>
-<td><code>
-profile stop <PROCESS>
-</code></td>
-<td>Stop profiler on {@code <PROCESS>}.
-</td>
-</tr>
-
-<tr>
-<td style="white-space:nowrap"><code>
-dumpheap [options] <PROCESS> <FILE>
-</code></td>
-<td>Dump the heap of {@code <PROCESS>}, write to {@code <FILE>}. <p>Options are:
-<ul>
- <li>{@code --user [<USER_ID>|current]}: When supplying a process name,
- specify user of process to dump; uses current user if not specified.
- <li>{@code -n}: Dump native heap instead of managed heap.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-set-debug-app [options] <PACKAGE>
-</code></td>
-<td>Set application {@code <PACKAGE>} to debug. <p>Options are:
-<ul>
- <li>{@code -w}: Wait for debugger when application starts.
- <li>{@code --persistent}: Retain this value.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-clear-debug-app
-</code></td>
-<td>Clear the package previous set for debugging with {@code set-debug-app}.
-</td>
-</tr>
-
-<tr>
-<td><code>
-monitor [options]
-</code></td>
-<td>Start monitoring for crashes or ANRs. <p>Options are:
-<ul>
- <li>{@code --gdb}: Start gdbserv on the given port at crash/ANR.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-screen-compat [on|off] <PACKAGE>
-</code></td>
-<td>Control <a href="{@docRoot}guide/practices/screen-compat-mode.html">screen
-compatibility</a> mode of {@code <PACKAGE>}.</p>
-</td>
-</tr>
-
-<tr>
-<td><code>
-display-size [reset|<WxH>]
-</code></td>
-<td>Override emulator/device display size.
-This command is helpful for testing your app across different screen sizes by mimicking a small
-screen resolution using a device with a large screen, and vice versa.
-<p>Example:<br><code>am display-size 1280x800</code>
-</td>
-</tr>
-
-<tr>
-<td><code>
-display-density <dpi>
-</code></td>
-<td>Override emulator/device display density.
-This command is helpful for testing your app across different screen densities on high-density
-screen environment using a low density screen, and vice versa.
-<p>Example:<br><code>am display-density 480</code>
-</td>
-</tr>
-
-<tr>
-<td><code>
-to-uri <INTENT>
-</code></td>
-<td>Print the given intent specification as a URI. <p>See the
-<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
-</td>
-</tr>
-
-<tr>
-<td><code>
-to-intent-uri <INTENT>
-</code></td>
-<td>Print the given intent specification as an {@code intent:} URI. <p>See the
-<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
-</td>
-</tr>
-</table>
-
-
-
-
-
-<h4 id="IntentSpec">
- <a href="" class="expandable" onclick="toggleExpandable(this,'.intents');
-return false">Specification for <INTENT> arguments</a></h4>
-
-<div class="intents" style="display:none">
-
-<p>For activity manager commands that take a {@code <INTENT>} argument, you can
-specify the intent with the following options:</p>
-
-<dl>
- <dt>{@code -a <ACTION>}</dt>
- <dd>Specify the intent action, such as "android.intent.action.VIEW".
- You can declare this only once.
-
- <dt>{@code -d <DATA_URI>}</dt>
- <dd>Specify the intent data URI, such as "content://contacts/people/1".
- You can declare this only once.
-
- <dt>{@code -t <MIME_TYPE>}</dt>
- <dd>Specify the intent MIME type, such as "image/png".
- You can declare this only once.
-
- <dt>{@code -c <CATEGORY>}</dt>
- <dd>Specify an intent category, such as "android.intent.category.APP_CONTACTS".
-
- <dt>{@code -n <COMPONENT>}</dt>
- <dd>Specify the component name with package name prefix to create an explicit intent, such
- as "com.example.app/.ExampleActivity".
-
- <dt>{@code -f <FLAGS>}</dt>
- <dd>Add flags to the intent, as supported by {@link
- android.content.Intent#setFlags setFlags()}.
-
- <dt>{@code --esn <EXTRA_KEY>}</dt>
- <dd>Add a null extra. This option is not supported for URI intents.
-
- <dt>{@code -e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE>}</dt>
- <dd>Add string data as a key-value pair.
-
- <dt>{@code --ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE>}</dt>
- <dd>Add boolean data as a key-value pair.
-
- <dt>{@code --ei <EXTRA_KEY> <EXTRA_INT_VALUE>}</dt>
- <dd>Add integer data as a key-value pair.
-
- <dt>{@code --el <EXTRA_KEY> <EXTRA_LONG_VALUE>}</dt>
- <dd>Add long data as a key-value pair.
-
- <dt>{@code --ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE>}</dt>
- <dd>Add float data as a key-value pair.
-
- <dt>{@code --eu <EXTRA_KEY> <EXTRA_URI_VALUE>}</dt>
- <dd>Add URI data as a key-value pair.
-
- <dt>{@code --ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>}</dt>
- <dd>Add a component name, which is converted and passed as
- a {@link android.content.ComponentName} object.
-
- <dt>{@code --eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]}</dt>
- <dd>Add an array of integers.
-
- <dt>{@code --ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]}</dt>
- <dd>Add an array of longs.
-
- <dt>{@code --efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]}</dt>
- <dd>Add an array of floats.
-
- <dt>{@code --grant-read-uri-permission}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}.
-
- <dt>{@code --grant-write-uri-permission}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
-
- <dt>{@code --debug-log-resolution}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_DEBUG_LOG_RESOLUTION}.
-
- <dt>{@code --exclude-stopped-packages}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_EXCLUDE_STOPPED_PACKAGES}.
-
- <dt>{@code --include-stopped-packages}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_INCLUDE_STOPPED_PACKAGES}.
-
- <dt>{@code --activity-brought-to-front}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_BROUGHT_TO_FRONT}.
-
- <dt>{@code --activity-clear-top}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.
-
- <dt>{@code --activity-clear-when-task-reset}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET}.
-
- <dt>{@code --activity-exclude-from-recents}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS}.
-
- <dt>{@code --activity-launched-from-history}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY}.
-
- <dt>{@code --activity-multiple-task}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}.
-
- <dt>{@code --activity-no-animation}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_ANIMATION}.
-
- <dt>{@code --activity-no-history}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_HISTORY}.
-
- <dt>{@code --activity-no-user-action}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_USER_ACTION}.
-
- <dt>{@code --activity-previous-is-top}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_PREVIOUS_IS_TOP}.
-
- <dt>{@code --activity-reorder-to-front}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_REORDER_TO_FRONT}.
-
- <dt>{@code --activity-reset-task-if-needed}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED}.
-
- <dt>{@code --activity-single-top}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}.
-
- <dt>{@code --activity-clear-task}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK}.
-
- <dt>{@code --activity-task-on-home}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_TASK_ON_HOME}.
-
- <dt>{@code --receiver-registered-only}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
-
- <dt>{@code --receiver-replace-pending}</dt>
- <dd>Include the flag {@link android.content.Intent#FLAG_RECEIVER_REPLACE_PENDING}.
-
- <dt>{@code --selector}</dt>
- <dd>Requires the use of {@code -d} and {@code -t} options to set the intent data and type.
-
- <dt>{@code <URI> <COMPONENT> <PACKAGE>}</dt>
- <dd>You can directly specify a URI, package name, and component name when not qualified
- by one of the above options. When an argument is unqualified, the tool assumes the argument
- is a URI if it contains a ":" (colon); it assumes the argument is a component name if it
- contains a "/" (forward-slash); otherwise it assumes the argument is a package name.
-
-</dl>
-</div><!-- end 'intents' -->
-<script>
- $(window).hashchange( function(){
- if ((location.hash == "#IntentSpec") && !($("#IntentSpec a").hasClass("expanded"))) {
- $("#IntentSpec a").click();
- }
- });
-</script>
-
-
-
-<h3 id="pm">Using package manager (pm)</h3>
-
-<p>Within an adb shell, you can issue commands with the package manager ({@code pm}) tool to
-perform actions and queries on application packages installed on the device. While in a shell,
-the syntax is:</p>
-<pre class="no-pretty-print">
-pm <command>
-</pre>
-
-<p>You can also issue a package manager command directly from adb
-without entering a remote shell. For example:</p>
-<pre class="no-pretty-print">
-adb shell pm uninstall com.example.MyApp
-</pre>
-
-<p class="table-caption"><strong>Table 3.</strong> Available package manager commands.</p>
-<table>
-<tr>
- <th>Command</th>
- <th>Description</th>
-</tr>
-
-<tr>
-<td><code>
-list packages [options] <FILTER>
-</code></td>
-<td>Prints all packages, optionally only
- those whose package name contains the text in {@code <FILTER>}. <p>Options:
-<ul>
- <li>{@code -f}: See their associated file.
- <li>{@code -d}: Filter to only show disabled packages.
- <li>{@code -e}: Filter to only show enabled packages.
- <li>{@code -s}: Filter to only show system packages.
- <li>{@code -3}: Filter to only show third party packages.
- <li>{@code -i}: See the installer for the packages.
- <li>{@code -u}: Also include uninstalled packages.
- <li>{@code --user <USER_ID>}: The user space to query.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-list permission-groups
-</code></td>
-<td>Prints all known permission groups.
-</td>
-</tr>
-
-<tr>
-<td><code>
-list permissions [options] <GROUP>
-</code></td>
-<td>Prints all known permissions, optionally only
- those in {@code <GROUP>}. <p>Options:
-<ul>
- <li>{@code -g}: Organize by group.
- <li>{@code -f}: Print all information.
- <li>{@code -s}: Short summary.
- <li>{@code -d}: Only list dangerous permissions.
- <li>{@code -u}: List only the permissions users will see.
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-list instrumentation
-</code></td>
-<td>List all test packages. <p>Options:
- <ul>
- <li>{@code -f}: List the APK file for the test package.
- <li>{@code <TARGET_PACKAGE>}: List test packages for only this app.
- </ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-list features
-</code></td>
-<td>Prints all features of the system.
-</td>
-</tr>
-
-<tr>
-<td><code>
-list libraries
-</code></td>
-<td>Prints all the libraries supported by the current device.
-</td>
-</tr>
-
-<tr>
-<td><code>
-list users
-</code></td>
-<td>Prints all users on the system.
-</td>
-</tr>
-
-<tr>
-<td><code>
-path <PACKAGE>
-</code></td>
-<td>Print the path to the APK of the given {@code <PACKAGE>}.
-</td>
-</tr>
-
-<tr>
-<td><code>
-install [options] <PATH>
-</code></td>
-<td>Installs a package (specified by {@code <PATH>}) to the system. <p>Options:
- <ul>
- <li>{@code -r}: Reinstall an exisiting app, keeping its data.
- <li>{@code -t}: Allow test APKs to be installed.
- <li>{@code -i <INSTALLER_PACKAGE_NAME>}: Specify the installer package name.
- <li>{@code -s}: Install package on the shared mass storage (such as sdcard).
- <li>{@code -f}: Install package on the internal system memory.
- <li>{@code -d}: Allow version code downgrade.
- </ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-uninstall [options] <PACKAGE>
-</code></td>
-<td>Removes a package from the system. <p>Options:
- <ul>
- <li>{@code -k}: Keep the data and cache directories around after package removal.
- </ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-clear <PACKAGE>
-</code></td>
-<td>Deletes all data associated with a package.
-</td>
-</tr>
-
-<tr>
-<td><code>
-enable <PACKAGE_OR_COMPONENT>
-</code></td>
-<td>Enable the given package or component (written as "package/class").
-</td>
-</tr>
-
-<tr>
-<td><code>
-disable <PACKAGE_OR_COMPONENT>
-</code></td>
-<td>Disable the given package or component (written as "package/class").
-</td>
-</tr>
-
-<tr>
-<td style="white-space:nowrap"><code>
-disable-user [options] <PACKAGE_OR_COMPONENT>
-</code></td>
-<td><p>Options:
- <ul>
- <li>{@code --user <USER_ID>}: The user to disable.
- </ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-grant <PACKAGE_PERMISSION>
-</code></td>
-<td>Grant permissions
- to applications. Only optional permissions the application has
- declared can be granted.
-</td>
-</tr>
-
-<tr>
-<td><code>
-revoke <PACKAGE_PERMISSION>
-</code></td>
-<td>Revoke permissions
- to applications. Only optional permissions the application has
- declared can be revoked.
-</td>
-</tr>
-
-<tr>
-<td><code>
-set-install-location <LOCATION>
-</code></td>
-<td>Changes the default install location. Location values:
-<ul>
- <li>{@code 0}: Auto—Let system decide the best location.
- <li>{@code 1}: Internal—install on internal device storage.
- <li>{@code 2}: External—install on external media.
-</ul>
-<p class="note"><strong>Note:</strong> This is only intended for debugging; using this can cause
- applications to break and other undesireable behavior.</p>
-</td>
-</tr>
-
-<tr>
-<td><code>
-get-install-location
-</code></td>
-<td>Returns the current install location. Return values:
-<ul>
- <li>{@code 0 [auto]}: Lets system decide the best location
- <li>{@code 1 [internal]}: Installs on internal device storage
- <li>{@code 2 [external]}: Installs on external media
-</ul>
-</td>
-</tr>
-
-<tr>
-<td><code>
-set-permission-enforced <PERMISSION> [true|false]
-</code></td>
-<td>Specifies whether the given permission should be enforced.
-</td>
-</tr>
-
-<tr>
-<td><code>
-trim-caches <DESIRED_FREE_SPACE>
-</code></td>
-<td>Trim cache files to reach the given free space.
-</td>
-</tr>
-
-<tr>
-<td><code>
-create-user <USER_NAME>
-</code></td>
-<td>Create a new user with the given {@code <USER_NAME>},
- printing the new user identifier of the user.
-</td>
-</tr>
-
-<tr>
-<td><code>
-remove-user <USER_ID>
-</code></td>
-<td>Remove the user with the given {@code <USER_IDENTIFIER>},
- deleting all data associated with that user
-</td>
-</tr>
-
-<tr>
-<td><code>
-get-max-users
-</code></td>
-<td>Prints the maximum number of users supported by the device.
-</td>
-</tr>
-
-</table>
-
-
-
-
-
-
-
-<h3 id="sqlite">Examining sqlite3 databases from a remote shell</h3>
-
-<p>From an adb remote shell, you can use the
-<a href="http://www.sqlite.org/sqlite.html">sqlite3</a> command-line program to
-manage SQLite databases created by Android applications. The
-<code>sqlite3</code> tool includes many useful commands, such as
-<code>.dump</code> to print out the contents of a table and
-<code>.schema</code> to print the SQL CREATE statement for an existing table.
-The tool also gives you the ability to execute SQLite commands on the fly.</p>
-
-<p>To use <code>sqlite3</code>, enter a remote shell on the emulator instance, as described above,
-then invoke the tool using the <code>sqlite3</code> command. Optionally, when invoking
-<code>sqlite3</code> you can specify the full path to the database you want to explore.
-Emulator/device instances store SQLite3 databases in the folder
-<code><span chatdir="1"><span chatindex="259474B4B070F261">/data/data/<em><package_name></em>/databases</span></span>/</code>. </p>
-
-<p>Here's an example: </p>
-
-<pre class="no-pretty-print">adb -s emulator-5554 shell
-# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
-SQLite version 3.3.12
-Enter ".help" for instructions
-<em>.... enter commands, then quit...</em>
-sqlite> .exit </pre>
-
-<p>Once you've invoked <code>sqlite3</code>, you can issue <code>sqlite3</code> commands in the
-shell. To exit and return to the adb remote shell, use <code>exit</code> or <code>CTRL+D</code>.
-
-
-
-
-<h3 id="screenrecord">Recording a device screen</h3>
-
-<p>The {@code screenrecord} command is a shell utility for recording the display of devices
- running Android 4.4 (API level 19) and higher. The utility records screen activity to an MPEG-4
- file, which you can then download and use as part of a video presentation. This utility is useful
- for developers who want to create promotional or training videos without using a separate
- recording device.</p>
-
-<p>To use the {@code screenrecord} from the command line, type the following:
-
-<pre>
-$ adb shell screenrecord /sdcard/demo.mp4
-</pre>
-
-<p>Stop the screen recording by pressing Ctrl-C, otherwise the recording stops automatically
-at three minutes or the time limit set by {@code --time-limit}.</p>
-
-<p>Here's an example recording session, using the adb shell to record the video and the
-{@code pull} command to download the file from the device:<p>
-
-<pre>
-$ adb shell
-shell@ $ screenrecord --verbose /sdcard/demo.mp4
-(press Ctrl-C to stop)
-shell@ $ exit
-$ adb pull /sdcard/demo.mp4
-</pre>
-
-<p>The {@code screenrecord} utility can record at any supported resolution and bit rate you
- request, while retaining the aspect ratio of the device display. The utility records at the native
- display resolution and orientation by default, with a maximum length of three minutes.</p>
-
-<p>There are some known limitations of the {@code screenrecord} utility that you should be aware
- of when using it:</p>
-
-<ul>
- <li>Some devices may not be able to record at their native display resolution.
- If you encounter problems with screen recording, try using a lower screen resolution.</li>
- <li>Rotation of the screen during recording is not supported. If the screen does rotate during
- recording, some of the screen is cut off in the recording.</li>
- <li>Audio is not recorded with the video file.</li>
-</ul>
-
-
-<p class="table-caption"><strong>Table 4.</strong> {@code screenrecord} options</p>
-
-<table>
- <tr>
- <th>Options</th>
- <th>Description</th>
- </tr>
-
- <tr>
- <td><code>--help</code>
- </td>
- <td>Displays a usage summary.</td>
- </tr>
-
- <tr>
- <td style="white-space:nowrap">
- <code>--size <WIDTHxHEIGHT></code>
- </td>
- <td>Sets the video size, for example: {@code 1280x720}. The default value is the device's main
- display resolution (if supported), 1280x720 if not. For best results, use a size supported
- by your device's Advanced Video Coding (AVC) encoder.</td>
- </tr>
-
- <tr>
- <td><code>--bit-rate <RATE></code></td>
- <td>Sets the video bit rate for the video, in megabits per second. The default value is 4Mbps.
- You can increase the bit rate to improve video quality or lower it for smaller movie
- files. The following example sets the recording bit rate to 6Mbps:
- <pre>screenrecord --bit-rate 6000000 /sdcard/demo.mp4</pre>
- </td>
- </tr>
-
- <tr>
- <td><code>--time-limit <TIME></code></td>
- <td>Sets the maximum recording time, in seconds. The default and maximum value is 180
- (3 minutes).</td>
- </tr>
-
- <tr>
- <td><code>--rotate</code></td>
- <td>Rotates the output 90 degrees. This feature is experimental.</td>
- </tr>
-
- <tr>
- <td><code>--verbose</code></td>
- <td>Displays log information on command line screen. If you do not set this option,
- the utility does not display any information while running.</td>
- </tr>
-
-</table>
-
-
-
-
-<h3 id="monkey">UI/Application Exerciser Monkey</h3>
-
-<p>The Monkey is a program that runs on your emulator or device and generates pseudo-random
-streams of user events such as clicks, touches, or gestures, as well as a number of system-level
-events. You can use the Monkey to stress-test applications that you are developing,
-in a random yet repeatable manner.</p>
-
-<p>The simplest way to use the monkey is with the following command, which launches your
-application and sends 500 pseudo-random events to it.</p>
-
-<pre class="no-pretty-print">adb shell monkey -v -p your.package.name 500</pre>
-
-<p>For more information about command options for Monkey, see the complete
-<a href="{@docRoot}tools/help/monkey.html" title="monkey">UI/Application Exerciser Monkey</a> documentation page.</p>
-
-
-
-
-
-<h3 id="othershellcommands">Other shell commands</h3>
-
-<p>For a list of all the available shell programs, use the following command:</p>
-
-<pre class="no-pretty-print">adb shell ls /system/bin</pre>
-
-<p>Help is available for most of the commands. </p>
-
-<p>Table 5 lists some of the more common adb shell commands.</p>
-
-<p class="table-caption"><strong>Table 5.</strong> Some other adb shell commands</p>
-<table>
-<tr>
- <th>Shell Command</th>
- <th>Description</th>
- <th>Comments</th>
-</tr>
-
-<tr>
-<td><code>dumpsys</code></td>
-<td>Dumps system data to the screen.</td>
-<td rowspan=4">The <a href="{@docRoot}tools/debugging/ddms.html">Dalvik Debug Monitor Server</a>
-(DDMS) tool offers integrated debug environment that you may find easier to use.</td>
-</tr>
-
-<tr>
-<td><code>dumpstate</code></td>
-<td>Dumps state to a file.</td>
-</tr>
-
-<tr>
-<td><code>logcat [option]... [filter-spec]...</code></td>
-<td>Enables system and app logging and prints output to the screen. </td>
-</tr>
-
-<tr>
-<td><code>dmesg</code></td>
-<td>Prints kernel debugging messages to the screen. </td>
-</tr>
-
-<tr>
-<td><code>start</code></td>
-<td>Starts (restarts) an emulator/device instance.</td>
-<td> </td>
-</tr>
-
-<tr>
-<td><code>stop</code></td>
-<td>Stops execution of an emulator/device instance.</td>
-<td> </td>
-</tr>
-
-</table>
-
-
-
-
-
-
-
-<a name="stdout"></a>
-<a name="usinglogcat"></a>
-<a name="outputformat"></a>
-<a name="filteringoutput"></a>
-<a name="stdout"></a>
-<a name="logcatoptions"></a>
-
-<h2 id="logcat">Enabling logcat logging</h2>
-
-<p>The Android logging system provides a mechanism for collecting and viewing system debug output. Logs from various applications and portions of the system are collected in a series of circular buffers, which then can be viewed and filtered by the <code>logcat</code> command.</p>
-
-<p>You can use the <code>logcat</code> command to view and follow the contents of the system's log buffers. The general usage is:</p>
-
-<pre class="no-pretty-print">[adb] logcat [option] ... [filter-spec] ...</pre>
-
-<p>You can use the <code>logcat</code> command from your development computer or from a remote adb shell in an emulator/device instance. To view log output in your development computer, you use</p>
-
-<pre class="no-pretty-print">adb logcat</pre>
-
-<p>and from a remote adb shell you use</p>
-
-<pre class="no-pretty-print">logcat</pre>
-
-<p>See <a href="{@docRoot}tools/debugging/debugging-log.html">Reading and Writing Logs</a> for complete information about logcat commend options and filter specifications.</p>
-
-
-
-
-
-<h2 id="stopping">Stopping the adb server</h2>
-
-<p>In some cases, you might need to terminate the adb server process and then restart it. For example, if adb does not respond to a command, you can terminate the server and restart it and that may resolve the problem. </p>
+<p>In some cases, you might need to terminate the adb server process and then restart it
+to resolve the problem (e.g., if adb does not respond to a command).</p>
<p>To stop the adb server, use the <code>kill-server</code> command.
You can then restart the server by issuing any other adb command. </p>
@@ -1457,4 +506,4 @@
and then start over from the beginning.
</li>
-</ol>
+</ol>
\ No newline at end of file
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 8abe1b4..0fac62d 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -30,20 +30,21 @@
</div>
</div>
- <p>ADT (Android Developer Tools) is a plugin for Eclipse that provides a suite of
+<p class="caution">
+ <strong>Important:</strong> Support for the Android Developer Tools (ADT) in Eclipse is ending,
+ per our <a href=
+ "http://android-developers.blogspot.com/2015/06/an-update-on-eclipse-android-developer.html"
+ class="external-link">announcement</a>. You should migrate your app development projects to
+ Android Studio as soon as possible. For more information on transitioning to Android Studio, see
+ <a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a>.
+</p>
+
+ <p>Android Developer Tools (ADT) is a plugin for Eclipse that provides a suite of
tools that are integrated with the Eclipse IDE. It offers you access to many features that help
you develop Android applications. ADT
provides GUI access to many of the command line SDK tools as well as a UI design tool for rapid
prototyping, designing, and building of your application's user interface.</p>
-<p class="note"><strong>Note:</strong>
-If you have been using Eclipse with ADT, be aware that <a
-href="{@docRoot}tools/studio/index.html">Android Studio</a> is now the official IDE
-for Android, so you should migrate to Android Studio to receive all the
-latest IDE updates. For help moving projects,
-see <a href="/sdk/installing/migrate.html">Migrating to Android
-Studio</a>.</p>
-
<p>If you still wish to use the ADT plugin for Eclipse, see
<a href="{@docRoot}sdk/installing/installing-adt.html">Installing Eclipse Plugin.</a>
</p>
diff --git a/docs/html/tools/help/index.jd b/docs/html/tools/help/index.jd
index 4c97d0c..f90d029 100644
--- a/docs/html/tools/help/index.jd
+++ b/docs/html/tools/help/index.jd
@@ -68,7 +68,10 @@
<dt><a href="{@docRoot}tools/help/adb.html">adb</a></dt>
<dd>Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with
an emulator instance or connected Android-powered device. It also provides access to the
- device shell for advanced command-line operations.</dd>
+ device shell.</dd>
+
+ <dt><a href="{@docRoot}tools/help/shell.html">ADB Shell Commands</a></dt>
+ <dd>Learn the commands available for advanced command-line operations.</dd>
<dt><a href="{@docRoot}tools/debugging/ddms.html">Dalvik Debug Monitor
Server (ddms)</a></dt>
@@ -109,11 +112,9 @@
<dt><a href="{@docRoot}tools/help/jobb.html">JOBB</a></dt>
<dd>Allows you to build encrypted and unencrypted
- <a href="{@docRoot}{@docRoot}google/play/expansion-files.html">APK expansion files</a> in Opaque
+ <a href="{@docRoot}google/play/expansion-files.html">APK expansion files</a> in Opaque
Binary Blob (OBB) format.</dd>
-<a href="{@docRoot}{@docRoot}google/play/expansion-files.html">APK expansion files</a>
-
<dt><a href="{@docRoot}tools/help/proguard.html">ProGuard</a></dt>
<dd>Shrinks, optimizes, and obfuscates your code by removing unused code and renaming
classes, fields, and methods with semantically obscure names.</dd>
diff --git a/docs/html/tools/help/shell.jd b/docs/html/tools/help/shell.jd
new file mode 100644
index 0000000..417c871
--- /dev/null
+++ b/docs/html/tools/help/shell.jd
@@ -0,0 +1,898 @@
+page.title=ADB Shell Commands
+parent.title=Tools
+parent.link=index.html
+page.tags=shell,adb,am,pm,screenrecord,screencap
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>In this document</h2>
+<ol>
+ <li><a href="#shellcommands">Issuing Shell Commands</a>
+ <li><a href="#am">Using activity manager (am)</a></li>
+ <li><a href="#pm">Using package manager (pm)</a></li>
+ <li><a href="#screencap">Taking a device screenshot</a></li>
+ <li><a href="#screenrecord">Recording a device screen</a></li>
+ <li><a href="#othershellcommands">Other shell commands</a></li>
+ </li>
+</ol>
+
+</div>
+</div>
+
+<p>The <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a> (adb) provides a Unix shell
+that you can use to run a variety of commands on an emulator or connected device. The command
+binaries are stored in the file system of the emulator or device, at <code>/system/bin/...</code>
+</p>
+
+<h2 id="shellcommands">Issuing Shell Commands</h2>
+
+<p>You can use the <code>shell</code> command to issue commands, with or without entering
+the adb remote shell on the emulator/device. To issue a single command without entering a
+remote shell, use the <code>shell</code> command like this: </p>
+
+ <pre class="no-pretty-print">adb [-d|-e|-s <serialNumber>] shell <shell_command></pre>
+
+<p>Or enter a remote shell on an emulator/device like this:</p>
+
+ <pre class="no-pretty-print">adb [-d|-e|-s <serialNumber>] shell</pre>
+
+<p>When you are ready to exit the remote shell, press CTRL+D or type
+<code>exit</code>. </p>
+
+
+
+
+
+<h2 id="am">Using activity manager (am)</h2>
+
+<p>Within an adb shell, you can issue commands with the activity manager ({@code am}) tool to
+perform various system actions, such as start an activity, force-stop a process,
+broadcast an intent, modify the device screen properties, and more. While in a shell,
+the syntax is:</p>
+<pre class="no-pretty-print">
+am <command>
+</pre>
+
+<p>You can also issue an activity manager command directly from adb
+without entering a remote shell. For example:</p>
+<pre class="no-pretty-print">
+adb shell am start -a android.intent.action.VIEW
+</pre>
+
+
+<p class="table-caption"><strong>Table 2.</strong> Available activity manager commands</p>
+<table>
+<tr>
+ <th>Command</th>
+ <th>Description</th>
+</tr>
+
+<tr>
+<td><code>
+start [options] <INTENT>
+</code></td>
+<td>Start an {@link android.app.Activity} specified by {@code <INTENT>}. <p>See the
+<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
+<p>Options are:
+<ul>
+ <li>{@code -D}: Enable debugging.
+ <li>{@code -W}: Wait for launch to complete.
+ <li>{@code --start-profiler <FILE>}: Start profiler and send results to {@code <FILE>}.
+ <li>{@code -P <FILE>}: Like <code>--start-profiler</code>,
+ but profiling stops when the app goes idle.
+ <li>{@code -R}: Repeat the activity launch {@code <COUNT>} times. Prior to each repeat,
+ the top activity will be finished.
+ <li>{@code -S}: Force stop the target app before starting the activity.
+ <li>{@code --opengl-trace}: Enable tracing of OpenGL functions.
+ <li>{@code --user <USER_ID> | current}: Specify which user to run as; if not
+ specified, then run as the current user.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+startservice [options] <INTENT>
+</code></td>
+<td>Start the {@link android.app.Service} specified by {@code <INTENT>}. <p>See the
+<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
+<p>Options are:
+<ul>
+ <li>{@code --user <USER_ID> | current}: Specify which user to run as; if not
+ specified, then run as the current user.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+force-stop <PACKAGE>
+</code></td>
+<td>Force stop everything associated with {@code <PACKAGE>} (the app's package name).
+</td>
+</tr>
+
+<tr>
+<td><code>
+kill [options] <PACKAGE>
+</code></td>
+<td> Kill all processes associated with {@code <PACKAGE>}
+ (the app's package name). This command kills only
+ processes that are safe to kill and that will not impact the user
+ experience.
+ <p>Options are:
+ <ul>
+ <li>{@code --user <USER_ID> | all | current}: Specify user whose processes to kill;
+ all users if not specified.
+ </ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+kill-all
+</code></td>
+<td>Kill all background processes.
+</td>
+</tr>
+
+<tr>
+<td><code>
+broadcast [options] <INTENT>
+</code></td>
+<td>Issue a broadcast intent. <p>See the
+<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
+<p>Options are:
+<ul>
+ <li>{@code [--user <USER_ID> | all | current]}: Specify which user to send to; if not
+ specified then send to all users.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+instrument [options] <COMPONENT>
+</code></td>
+<td>Start monitoring with an {@link android.app.Instrumentation} instance.
+ Typically the target {@code <COMPONENT>}
+ is the form {@code <TEST_PACKAGE>/<RUNNER_CLASS>}. <p>Options are:
+<ul>
+ <li>{@code -r}: Print raw results (otherwise decode
+ {@code <REPORT_KEY_STREAMRESULT>}). Use with
+ {@code [-e perf true]} to generate raw output for performance measurements.
+
+ <li>{@code -e <NAME> <VALUE>}: Set argument {@code <NAME>} to {@code <VALUE>}.
+ For test runners a common form is {@code
+ -e <testrunner_flag> <value>[,<value>...]}.
+
+ <li>{@code -p <FILE>}: Write profiling data to {@code <FILE>}.
+
+ <li>{@code -w}: Wait for instrumentation to finish before returning. Required for
+ test runners.
+
+ <li>{@code --no-window-animation}: Turn off window animations while running.
+ <li>{@code --user <USER_ID> | current}: Specify which user instrumentation runs in;
+ current user if not specified.
+</ul>
+
+</td>
+</tr>
+
+<tr>
+<td><code>
+profile start <PROCESS> <FILE>
+</code></td>
+<td>Start profiler on {@code <PROCESS>}, write results to {@code <FILE>}.
+</td>
+</tr>
+
+<tr>
+<td><code>
+profile stop <PROCESS>
+</code></td>
+<td>Stop profiler on {@code <PROCESS>}.
+</td>
+</tr>
+
+<tr>
+<td style="white-space:nowrap"><code>
+dumpheap [options] <PROCESS> <FILE>
+</code></td>
+<td>Dump the heap of {@code <PROCESS>}, write to {@code <FILE>}. <p>Options are:
+<ul>
+ <li>{@code --user [<USER_ID>|current]}: When supplying a process name,
+ specify user of process to dump; uses current user if not specified.
+ <li>{@code -n}: Dump native heap instead of managed heap.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+set-debug-app [options] <PACKAGE>
+</code></td>
+<td>Set application {@code <PACKAGE>} to debug. <p>Options are:
+<ul>
+ <li>{@code -w}: Wait for debugger when application starts.
+ <li>{@code --persistent}: Retain this value.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+clear-debug-app
+</code></td>
+<td>Clear the package previous set for debugging with {@code set-debug-app}.
+</td>
+</tr>
+
+<tr>
+<td><code>
+monitor [options]
+</code></td>
+<td>Start monitoring for crashes or ANRs. <p>Options are:
+<ul>
+ <li>{@code --gdb}: Start gdbserv on the given port at crash/ANR.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+screen-compat [on|off] <PACKAGE>
+</code></td>
+<td>Control <a href="{@docRoot}guide/practices/screen-compat-mode.html">screen
+compatibility</a> mode of {@code <PACKAGE>}.</p>
+</td>
+</tr>
+
+<tr>
+<td><code>
+display-size [reset|<WxH>]
+</code></td>
+<td>Override emulator/device display size.
+This command is helpful for testing your app across different screen sizes by mimicking a small
+screen resolution using a device with a large screen, and vice versa.
+<p>Example:<br><code>am display-size 1280x800</code>
+</td>
+</tr>
+
+<tr>
+<td><code>
+display-density <dpi>
+</code></td>
+<td>Override emulator/device display density.
+This command is helpful for testing your app across different screen densities on high-density
+screen environment using a low density screen, and vice versa.
+<p>Example:<br><code>am display-density 480</code>
+</td>
+</tr>
+
+<tr>
+<td><code>
+to-uri <INTENT>
+</code></td>
+<td>Print the given intent specification as a URI. <p>See the
+<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
+</td>
+</tr>
+
+<tr>
+<td><code>
+to-intent-uri <INTENT>
+</code></td>
+<td>Print the given intent specification as an {@code intent:} URI. <p>See the
+<a href="#IntentSpec">Specification for <INTENT> arguments</a>.
+</td>
+</tr>
+</table>
+
+
+
+
+
+<h3 id="IntentSpec">
+ <a href="" class="expandable" onclick="toggleExpandable(this,'.intents');
+return false">Specification for <INTENT> arguments</a></h3>
+
+<div class="intents" style="display:none">
+
+<p>For activity manager commands that take a {@code <INTENT>} argument, you can
+specify the intent with the following options:</p>
+
+<dl>
+ <dt>{@code -a <ACTION>}</dt>
+ <dd>Specify the intent action, such as "android.intent.action.VIEW".
+ You can declare this only once.
+
+ <dt>{@code -d <DATA_URI>}</dt>
+ <dd>Specify the intent data URI, such as "content://contacts/people/1".
+ You can declare this only once.
+
+ <dt>{@code -t <MIME_TYPE>}</dt>
+ <dd>Specify the intent MIME type, such as "image/png".
+ You can declare this only once.
+
+ <dt>{@code -c <CATEGORY>}</dt>
+ <dd>Specify an intent category, such as "android.intent.category.APP_CONTACTS".
+
+ <dt>{@code -n <COMPONENT>}</dt>
+ <dd>Specify the component name with package name prefix to create an explicit intent, such
+ as "com.example.app/.ExampleActivity".
+
+ <dt>{@code -f <FLAGS>}</dt>
+ <dd>Add flags to the intent, as supported by {@link
+ android.content.Intent#setFlags setFlags()}.
+
+ <dt>{@code --esn <EXTRA_KEY>}</dt>
+ <dd>Add a null extra. This option is not supported for URI intents.
+
+ <dt>{@code -e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE>}</dt>
+ <dd>Add string data as a key-value pair.
+
+ <dt>{@code --ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE>}</dt>
+ <dd>Add boolean data as a key-value pair.
+
+ <dt>{@code --ei <EXTRA_KEY> <EXTRA_INT_VALUE>}</dt>
+ <dd>Add integer data as a key-value pair.
+
+ <dt>{@code --el <EXTRA_KEY> <EXTRA_LONG_VALUE>}</dt>
+ <dd>Add long data as a key-value pair.
+
+ <dt>{@code --ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE>}</dt>
+ <dd>Add float data as a key-value pair.
+
+ <dt>{@code --eu <EXTRA_KEY> <EXTRA_URI_VALUE>}</dt>
+ <dd>Add URI data as a key-value pair.
+
+ <dt>{@code --ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>}</dt>
+ <dd>Add a component name, which is converted and passed as
+ a {@link android.content.ComponentName} object.
+
+ <dt>{@code --eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]}</dt>
+ <dd>Add an array of integers.
+
+ <dt>{@code --ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]}</dt>
+ <dd>Add an array of longs.
+
+ <dt>{@code --efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]}</dt>
+ <dd>Add an array of floats.
+
+ <dt>{@code --grant-read-uri-permission}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+
+ <dt>{@code --grant-write-uri-permission}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
+
+ <dt>{@code --debug-log-resolution}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_DEBUG_LOG_RESOLUTION}.
+
+ <dt>{@code --exclude-stopped-packages}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_EXCLUDE_STOPPED_PACKAGES}.
+
+ <dt>{@code --include-stopped-packages}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_INCLUDE_STOPPED_PACKAGES}.
+
+ <dt>{@code --activity-brought-to-front}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_BROUGHT_TO_FRONT}.
+
+ <dt>{@code --activity-clear-top}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.
+
+ <dt>{@code --activity-clear-when-task-reset}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET}.
+
+ <dt>{@code --activity-exclude-from-recents}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS}.
+
+ <dt>{@code --activity-launched-from-history}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY}.
+
+ <dt>{@code --activity-multiple-task}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}.
+
+ <dt>{@code --activity-no-animation}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_ANIMATION}.
+
+ <dt>{@code --activity-no-history}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_HISTORY}.
+
+ <dt>{@code --activity-no-user-action}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_NO_USER_ACTION}.
+
+ <dt>{@code --activity-previous-is-top}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_PREVIOUS_IS_TOP}.
+
+ <dt>{@code --activity-reorder-to-front}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_REORDER_TO_FRONT}.
+
+ <dt>{@code --activity-reset-task-if-needed}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED}.
+
+ <dt>{@code --activity-single-top}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}.
+
+ <dt>{@code --activity-clear-task}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK}.
+
+ <dt>{@code --activity-task-on-home}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_ACTIVITY_TASK_ON_HOME}.
+
+ <dt>{@code --receiver-registered-only}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
+
+ <dt>{@code --receiver-replace-pending}</dt>
+ <dd>Include the flag {@link android.content.Intent#FLAG_RECEIVER_REPLACE_PENDING}.
+
+ <dt>{@code --selector}</dt>
+ <dd>Requires the use of {@code -d} and {@code -t} options to set the intent data and type.
+
+ <dt>{@code <URI> <COMPONENT> <PACKAGE>}</dt>
+ <dd>You can directly specify a URI, package name, and component name when not qualified
+ by one of the above options. When an argument is unqualified, the tool assumes the argument
+ is a URI if it contains a ":" (colon); it assumes the argument is a component name if it
+ contains a "/" (forward-slash); otherwise it assumes the argument is a package name.
+
+</dl>
+</div><!-- end 'intents' -->
+<script>
+ $(window).hashchange( function(){
+ if ((location.hash == "#IntentSpec") && !($("#IntentSpec a").hasClass("expanded"))) {
+ $("#IntentSpec a").click();
+ }
+ });
+</script>
+
+
+
+<h2 id="pm">Using package manager (pm)</h2>
+
+<p>Within an adb shell, you can issue commands with the package manager ({@code pm}) tool to
+perform actions and queries on application packages installed on the device. While in a shell,
+the syntax is:</p>
+<pre class="no-pretty-print">
+pm <command>
+</pre>
+
+<p>You can also issue a package manager command directly from adb
+without entering a remote shell. For example:</p>
+<pre class="no-pretty-print">
+adb shell pm uninstall com.example.MyApp
+</pre>
+
+<p class="table-caption"><strong>Table 3.</strong> Available package manager commands.</p>
+<table>
+<tr>
+ <th>Command</th>
+ <th>Description</th>
+</tr>
+
+<tr>
+<td><code>
+list packages [options] <FILTER>
+</code></td>
+<td>Prints all packages, optionally only
+ those whose package name contains the text in {@code <FILTER>}. <p>Options:
+<ul>
+ <li>{@code -f}: See their associated file.
+ <li>{@code -d}: Filter to only show disabled packages.
+ <li>{@code -e}: Filter to only show enabled packages.
+ <li>{@code -s}: Filter to only show system packages.
+ <li>{@code -3}: Filter to only show third party packages.
+ <li>{@code -i}: See the installer for the packages.
+ <li>{@code -u}: Also include uninstalled packages.
+ <li>{@code --user <USER_ID>}: The user space to query.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+list permission-groups
+</code></td>
+<td>Prints all known permission groups.
+</td>
+</tr>
+
+<tr>
+<td><code>
+list permissions [options] <GROUP>
+</code></td>
+<td>Prints all known permissions, optionally only
+ those in {@code <GROUP>}. <p>Options:
+<ul>
+ <li>{@code -g}: Organize by group.
+ <li>{@code -f}: Print all information.
+ <li>{@code -s}: Short summary.
+ <li>{@code -d}: Only list dangerous permissions.
+ <li>{@code -u}: List only the permissions users will see.
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+list instrumentation
+</code></td>
+<td>List all test packages. <p>Options:
+ <ul>
+ <li>{@code -f}: List the APK file for the test package.
+ <li>{@code <TARGET_PACKAGE>}: List test packages for only this app.
+ </ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+list features
+</code></td>
+<td>Prints all features of the system.
+</td>
+</tr>
+
+<tr>
+<td><code>
+list libraries
+</code></td>
+<td>Prints all the libraries supported by the current device.
+</td>
+</tr>
+
+<tr>
+<td><code>
+list users
+</code></td>
+<td>Prints all users on the system.
+</td>
+</tr>
+
+<tr>
+<td><code>
+path <PACKAGE>
+</code></td>
+<td>Print the path to the APK of the given {@code <PACKAGE>}.
+</td>
+</tr>
+
+<tr>
+<td><code>
+install [options] <PATH>
+</code></td>
+<td>Installs a package (specified by {@code <PATH>}) to the system. <p>Options:
+ <ul>
+ <li>{@code -l}: Install the package with forward lock.
+ <li>{@code -r}: Reinstall an exisiting app, keeping its data.
+ <li>{@code -t}: Allow test APKs to be installed.
+ <li>{@code -i <INSTALLER_PACKAGE_NAME>}: Specify the installer package name.
+ <li>{@code -s}: Install package on the shared mass storage (such as sdcard).
+ <li>{@code -f}: Install package on the internal system memory.
+ <li>{@code -d}: Allow version code downgrade.
+ </ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+uninstall [options] <PACKAGE>
+</code></td>
+<td>Removes a package from the system. <p>Options:
+ <ul>
+ <li>{@code -k}: Keep the data and cache directories around after package removal.
+ </ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+clear <PACKAGE>
+</code></td>
+<td>Deletes all data associated with a package.
+</td>
+</tr>
+
+<tr>
+<td><code>
+enable <PACKAGE_OR_COMPONENT>
+</code></td>
+<td>Enable the given package or component (written as "package/class").
+</td>
+</tr>
+
+<tr>
+<td><code>
+disable <PACKAGE_OR_COMPONENT>
+</code></td>
+<td>Disable the given package or component (written as "package/class").
+</td>
+</tr>
+
+<tr>
+<td style="white-space:nowrap"><code>
+disable-user [options] <PACKAGE_OR_COMPONENT>
+</code></td>
+<td><p>Options:
+ <ul>
+ <li>{@code --user <USER_ID>}: The user to disable.
+ </ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+grant <PACKAGE_PERMISSION>
+</code></td>
+<td>Grant permissions
+ to applications. Only optional permissions the application has
+ declared can be granted.
+</td>
+</tr>
+
+<tr>
+<td><code>
+revoke <PACKAGE_PERMISSION>
+</code></td>
+<td>Revoke permissions
+ to applications. Only optional permissions the application has
+ declared can be revoked.
+</td>
+</tr>
+
+<tr>
+<td><code>
+set-install-location <LOCATION>
+</code></td>
+<td>Changes the default install location. Location values:
+<ul>
+ <li>{@code 0}: Auto—Let system decide the best location.
+ <li>{@code 1}: Internal—install on internal device storage.
+ <li>{@code 2}: External—install on external media.
+</ul>
+<p class="note"><strong>Note:</strong> This is only intended for debugging; using this can cause
+ applications to break and other undesireable behavior.</p>
+</td>
+</tr>
+
+<tr>
+<td><code>
+get-install-location
+</code></td>
+<td>Returns the current install location. Return values:
+<ul>
+ <li>{@code 0 [auto]}: Lets system decide the best location
+ <li>{@code 1 [internal]}: Installs on internal device storage
+ <li>{@code 2 [external]}: Installs on external media
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><code>
+set-permission-enforced <PERMISSION> [true|false]
+</code></td>
+<td>Specifies whether the given permission should be enforced.
+</td>
+</tr>
+
+<tr>
+<td><code>
+trim-caches <DESIRED_FREE_SPACE>
+</code></td>
+<td>Trim cache files to reach the given free space.
+</td>
+</tr>
+
+<tr>
+<td><code>
+create-user <USER_NAME>
+</code></td>
+<td>Create a new user with the given {@code <USER_NAME>},
+ printing the new user identifier of the user.
+</td>
+</tr>
+
+<tr>
+<td><code>
+remove-user <USER_ID>
+</code></td>
+<td>Remove the user with the given {@code <USER_IDENTIFIER>},
+ deleting all data associated with that user
+</td>
+</tr>
+
+<tr>
+<td><code>
+get-max-users
+</code></td>
+<td>Prints the maximum number of users supported by the device.
+</td>
+</tr>
+
+</table>
+
+
+<h2 id="screencap">Taking a device screenshot</h2>
+
+<p>The {@code screencap} command is a shell utility for taking a screenshot of a device display.
+While in a shell, the syntax is:
+</p>
+
+<pre class="no-pretty-print">
+screencap <filename>
+</pre>
+
+
+<p>To use the {@code screencap} from the command line, type the following:
+
+<pre>
+$ adb shell screencap /sdcard/screen.png
+</pre>
+
+<p>Here's an example screenshot session, using the adb shell to capture the screenshot and the
+{@code pull} command to download the file from the device:<p>
+
+<pre>
+$ adb shell
+shell@ $ screencap /sdcard/screen.png
+shell@ $ exit
+$ adb pull /sdcard/screen.png
+</pre>
+
+
+<h2 id="screenrecord">Recording a device screen</h2>
+
+<p>The {@code screenrecord} command is a shell utility for recording the display of devices
+ running Android 4.4 (API level 19) and higher. The utility records screen activity to an MPEG-4
+ file.</p>
+
+<p class="note"><strong>Note:</strong> Audio is not recorded with the video file.</p>
+
+<p>A developer can use this file to create promotional or training videos. While in a shell, the syntax is:</p>
+
+<pre class="no-pretty-print">
+screenrecord [options] <filename>
+</pre>
+
+<p>To use {@code screenrecord} from the command line, type the following:
+
+<pre>
+$ adb shell screenrecord /sdcard/demo.mp4
+</pre>
+
+<p>Stop the screen recording by pressing Ctrl-C, otherwise the recording stops automatically
+at three minutes or the time limit set by {@code --time-limit}.</p>
+
+<p>To begin recording your device screen, run the {@code screenrecord} command to record
+the video. Then, run the {@code pull} command to download the video from the device to the host
+computer. Here's an example recording session:<p>
+
+<pre>
+$ adb shell
+shell@ $ screenrecord --verbose /sdcard/demo.mp4
+(press Ctrl-C to stop)
+shell@ $ exit
+$ adb pull /sdcard/demo.mp4
+</pre>
+
+<p>The {@code screenrecord} utility can record at any supported resolution and bit rate you
+ request, while retaining the aspect ratio of the device display. The utility records at the native
+ display resolution and orientation by default, with a maximum length of three minutes.</p>
+
+<p>There are some known limitations of the {@code screenrecord} utility that you should be aware
+ of when using it:</p>
+
+<ul>
+ <li>Some devices may not be able to record at their native display resolution.
+ If you encounter problems with screen recording, try using a lower screen resolution.</li>
+ <li>Rotation of the screen during recording is not supported. If the screen does rotate during
+ recording, some of the screen is cut off in the recording.</li>
+</ul>
+
+
+<p class="table-caption"><strong>Table 4.</strong> {@code screenrecord} options</p>
+
+<table>
+ <tr>
+ <th>Options</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><code>--help</code>
+ </td>
+ <td>Displays command syntax and options</td>
+ </tr>
+
+ <tr>
+ <td style="white-space:nowrap">
+ <code>--size <WIDTHxHEIGHT></code>
+ </td>
+ <td>Sets the video size: {@code 1280x720}. The default value is the device's native
+ display resolution (if supported), 1280x720 if not. For best results, use a size supported
+ by your device's Advanced Video Coding (AVC) encoder.</td>
+ </tr>
+
+ <tr>
+ <td><code>--bit-rate <RATE></code></td>
+ <td>Sets the video bit rate for the video, in megabits per second. The default value is 4Mbps.
+ You can increase the bit rate to improve video quality, but doing so results in larger movie
+ files. The following example sets the recording bit rate to 6Mbps:
+ <pre>screenrecord --bit-rate 6000000 /sdcard/demo.mp4</pre>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>--time-limit <TIME></code></td>
+ <td>Sets the maximum recording time, in seconds. The default and maximum value is 180
+ (3 minutes).</td>
+ </tr>
+
+ <tr>
+ <td><code>--rotate</code></td>
+ <td>Rotates the output 90 degrees. This feature is experimental.</td>
+ </tr>
+
+ <tr>
+ <td><code>--verbose</code></td>
+ <td>Displays log information on the command-line screen. If you do not set this option,
+ the utility does not display any information while running.</td>
+ </tr>
+
+</table>
+
+
+<h2 id="othershellcommands">Other shell commands</h2>
+
+<p>For a list of all the available shell programs, use the following command:</p>
+
+<pre class="no-pretty-print">adb shell ls /system/bin</pre>
+
+<p>Help is available for most of the commands. </p>
+
+<p>Table 5 lists some of the more common adb shell commands.</p>
+
+<p class="table-caption"><strong>Table 5.</strong> Some other adb shell commands</p>
+<table>
+<tr>
+ <th>Shell Command</th>
+ <th>Description</th>
+ <th>Comments</th>
+</tr>
+
+<tr>
+<td><code>dumpsys</code></td>
+<td>Dumps system data to the screen.</td>
+<td rowspan=4">The <a href="{@docRoot}tools/debugging/ddms.html">Dalvik Debug Monitor Server</a>
+(DDMS) tool offers integrated debug environment that you may find easier to use.</td>
+</tr>
+
+<tr>
+<td><code>dumpstate</code></td>
+<td>Dumps state to a file.</td>
+</tr>
+
+<tr>
+<td><code>logcat [option]... [filter-spec]...</code></td>
+<td>Enables system and app logging and prints output to the screen. </td>
+</tr>
+
+<tr>
+<td><code>dmesg</code></td>
+<td>Prints kernel debugging messages to the screen. </td>
+</tr>
+
+<tr>
+<td><code>start</code></td>
+<td>Starts (restarts) an emulator/device instance.</td>
+<td> </td>
+</tr>
+
+<tr>
+<td><code>stop</code></td>
+<td>Stops execution of an emulator/device instance.</td>
+<td> </td>
+</tr>
+
+</table>
\ No newline at end of file
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 326fbe2..934b262 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -25,6 +25,36 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>SDK Tools, Revision 24.3.3</a> <em>(June 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+
+ <dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 19 or later.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed issues with using Ant build tasks with the Eclipse ADT build structure. </li>
+ <li>Fixed the emulator boot problem on Mac OS X 10.8.5.</li>
+ </ul>
+ </dd>
+ </div>
+</div>
+
+
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>SDK Tools, Revision 24.3.2</a> <em>(June 2015)</em>
</p>
diff --git a/docs/html/tools/studio/eclipse-transition-guide.jd b/docs/html/tools/studio/eclipse-transition-guide.jd
new file mode 100644
index 0000000..aaacbe3b
--- /dev/null
+++ b/docs/html/tools/studio/eclipse-transition-guide.jd
@@ -0,0 +1,773 @@
+page.title=Transition Guide for Eclipse ADT
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+ <ol>
+ <li><a href="#project-structure">Project Structure</a></li>
+ <li><a href="#manifest-settings">Manifest Settings</a></li>
+ <li><a href="#dependencies">Dependencies</a></li>
+ <li><a href="#build-process">Gradle-based Build Process</a></li>
+ <li><a href="#debug-inspect">Debugging and Code Inspections</a></li>
+ <li><a href="#resource-optimization">Resource Optimization</a></li>
+ <li><a href="#signing">App Signing</a></li>
+ <li><a href="#support-lib">Android Support Repository and Google Play services Repository</a></li>
+ <li><a href="#app-package">App Packaging</a></li>
+ <li><a href="#software-updates">Software Updates </a></li>
+ <li><a href="#version-control">Version Control</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a class="external-link"
+ href="http://confluence.jetbrains.com/display/IntelliJIDEA/FAQ+on+Migrating+to+IntelliJ+IDEA">
+ IntelliJ FAQ on migrating to IntelliJ IDEA</a></li>
+ <li><a class="external-link"
+ href="https://confluence.jetbrains.com/display/IntelliJIDEA/IntelliJ+IDEA+for+Eclipse+Users">
+ IntelliJ IntelliJ for Eclipse Users</a></li>
+ <li><a href="{@docRoot}tools/studio/index.html">Android Studio Overview</a> </li>
+ </ol>
+
+</div>
+</div>
+
+
+<p>This document describes the differences between Eclipse ADT and Android Studio, including project
+ structure, build system, debugging, and application packaging. This guide is intended to help you
+ transition to using Android Studio as your development environment.</p>
+
+<h2 id="project-structure">Project Structure </h2>
+<p>Eclipse provides workspaces as a common area for grouping related projects, configurations, and
+settings. In Android Studio, each instance of Android Studio contains a top-level project with one
+or more app modules. Each app module folder contains the equivalent to an Eclipse
+project, the complete source sets for that module, including {@code src/main} and
+{@code src/androidTest} directories, resources, build file, and the Android manifest. In general,
+to update and build your app you modify the files under each module's
+{@code src/main} directory for source code updates, the <code>gradle.build</code> file for
+build specification, and the files under {@code src/androidTest} directory for test case creation. </p>
+
+<p>You can also customize the view of the project files in Android Studio to focus on specific
+aspects of your app development: </p>
+
+<ul>
+ <li><em>Packages</em> </li>
+ <li><em>Project Files</em> </li>
+ <li><em>Scratches</em> </li>
+ <li><em>Problems</em> </li>
+ <li><em>Production</em> </li>
+ <li><em>Tests</em> </li>
+</ul>
+
+
+<p>The following table shows the general mapping of the Eclipse ADT project structure and file
+locations to Android Studio.</p>
+
+<p class="table-caption" id="table-project-structure-mapping">
+ <strong>Table 1.</strong> Project structure mapping.</p>
+
+<table>
+ <tr>
+ <th scope="col">Eclipse ADT</th>
+ <th scope="col">Android Studio</th>
+ </tr>
+
+ <tr>
+ <td>Workspace </td>
+ <td>Project </td>
+ </tr>
+
+ <tr>
+ <td>Project </td>
+ <td>Module </td>
+ </tr>
+
+ <tr>
+ <td>Project-specific JRE </td>
+ <td>Module JDK </td>
+ </tr>
+
+ <tr>
+ <td>Classpath variable </td>
+ <td>Path variable</td>
+ </tr>
+
+ <tr>
+ <td>Project dependency</td>
+ <td>Module dependency</td>
+ </tr>
+
+ <tr>
+ <td>Library Module</td>
+ <td>Library </td>
+ </tr>
+
+ <tr>
+ <td><code>AndroidManifest.xml</code></td>
+ <td><code>app/src/main/AndroidManifest.xml</code> </td>
+ </tr>
+ <tr>
+ <td><code>assets/</code></td>
+ <td><code>app/src/main/assets</code> </td>
+ </tr>
+ <tr>
+ <td><code>res/</code></td>
+ <td><code>app/src/main/res/</code> </td>
+ </tr>
+ <tr>
+ <td><code>src/</code></td>
+ <td><code>app/src/main/java/ </code> </td>
+ </tr>
+ <tr>
+ <td><code>tests/src/</code></td>
+ <td><code>app/src/androidTest/java/</code> </td>
+ </tr>
+
+ </table>
+
+
+
+<p>Table 2 shows Eclipse ADT and Android Studio project views. </p>
+
+<p class="table-caption" id="table2">
+ <strong>Table 2.</strong> Comparing project views.</p>
+<table>
+ <tbody><tr>
+ <th>Eclipse ADT</th>
+ <th>Android Studio Project View</th>
+ <th>Android Studio Android View</th>
+ </tr>
+ <tr>
+ <td><img src="{@docRoot}images/tools/eclipse-notepad-pre-import--structure.png"/> </td>
+ <td><img src="{@docRoot}images/tools/studio-import-project-structure-project.png"/> </td>
+ <td><img src="{@docRoot}images/tools/studio-import-project-structure-android.png"/> </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<p class="note"><strong>Note:</strong> Multiple instances of Android Studio can be used to develop
+independent projects. </p>
+
+
+
+
+<h2 id="manifest-settings">Manifest Settings</h2>
+<p>Android Studio and <a href="http://www.gradle.org">Gradle</a>-based builds support
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>,
+which are combinations of <code>productFlavor</code> and <code>buildTypes</code>, to customize
+your build outputs. To support these custom builds, several elements in the
+<code>AndroidManifest.xml</code> file are now properties in the <code>defaultConfig</code> and
+<code>productFlavors</code> blocks in the <code>build.gradle</code> file. The import process
+copies these manifest settings to the properties in the <code>build.gradle</code> file.
+These properties overwrite the settings in any other manifest files as shown in table 3. </p>
+
+<p class="table-caption" id="table-manifest-gradle-settings">
+ <strong>Table 3.</strong> Manifest and Gradle property settings.</p>
+<table>
+ <tr>
+ <th scope="col">Manifest Setting</th>
+ <th scope="col">build.gradle Setting</th>
+ </tr>
+ <tr>
+ <td><code><uses-sdk</code> <br>
+ <p><code>android:minSdkVersion</code></p>
+ <p><code>android:targetSdkVersion /></code></p>
+ </td>
+ <td> <br>
+ <p><code>minSdkVersion</code></p>
+ <p><code>targetSdkVersion</code></p> </td>
+ </tr>
+ <tr>
+ <td><code><manifest</code>
+ <p>package (Required in the default manifest file.) </p>
+ <p><code>android:versionCode</code></p>
+ <p><code>android:versionName /></code></p>
+ </td>
+ <td> <br>
+ <p><code>applicationId</code> (See
+ <a href="{@docRoot}tools/studio/index.html#app-id"> Application ID
+ for Package Identification</a>)</p>
+ <p><code>versionCode</code></p>
+ <p><code>versionName</code></p> </td>
+ </tr>
+
+ </table>
+
+
+<p>Although these settings may no longer appear in the default app manifest file, they are still
+valid manifest entries and may still appear in manifests from older projects, imported projects,
+dependencies, and libraries.</p>
+
+<p>The <code>package</code> element must still be specified in the manifest file. It is used in
+your source code to refer to your <code>R</code> class and to resolve any relative activity/service
+registrations. </p>
+
+<p class="note"><strong>Note:</strong> When multiple manifests are present in your app, for
+example a library manifest and a <code>src/main/</code> manifest, the build process combines
+the manifest settings into a single merged manifest based on the manifest priority and
+manifest merge settings. For more information about the manifest merge process and merge settings,
+see
+<a href="{@docRoot}tools/building/manifest-merger.html"> Manifest Merger</a>. </p>
+
+
+<h2>Application ID for package identification </h2>
+<p>With the Android build system, the <code>applicationId</code> attribute is used to
+uniquely identify application packages for publishing. The application ID is set in the
+<code>android</code> section of the <code>build.gradle</code> file. This field is populated in the
+build file as part of the migration process. </p>
+
+<pre>
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1"
+
+ defaultConfig {
+ <strong>applicationId "com.example.my.app"</strong>
+ minSdkVersion 15
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ ...
+</pre>
+
+<p class="note"><strong>Note:</strong> The <code>applicationId</code> is specified only in your
+<code>build.gradle</code> file, and not in the <code>AndroidManifest.xml</code> file.</p>
+
+<p><a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants">Build variants</a>
+enable you to uniquely identify different
+packages for each product flavor and build type. The application ID in the build type setting can
+be added as a suffix to the ID specified for the product flavors. The following example adds the
+<code>.debug</code> suffix to the application ID of the <code>pro</code> and <code>free</code>
+product flavors: </p>
+
+<pre>
+productFlavors {
+ pro {
+ applicationId = "com.example.my.pkg.pro"
+ }
+ free {
+ applicationId = "com.example.my.pkg.free"
+ }
+}
+
+buildTypes {
+ debug {
+ applicationIdSuffix ".debug"
+ }
+}
+....
+</pre>
+
+
+
+<h2 id="dependencies">Dependencies</h2>
+<p>During the import process, Android Studio imports the current Eclipse ADT dependencies and
+downloads any project libraries as Android Studio modules. The dependency declarations are added to
+the <code>build.gradle</code> file. The declarations include a
+<a href="#scopes">dependency scope</a>, such as
+<code>compile</code>, to specify in which builds the dependency is included. </p>
+
+<p>The following example shows how to add an external library JAR dependency so it's included in
+each compile:</p>
+
+<pre>
+dependencies {
+ compile files('libs/*.jar')
+}
+
+android {
+ ...
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Android Studio supports the Android ARchive (AAR) format
+for the distribution of Android library projects as dependencies. For more information, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+<p>The import process replaces any well-known source libraries, binary libraries, and JAR files
+that have known Maven coordinates with Maven dependencies, so you no longer need to
+maintain these dependencies manually. </p>
+
+<p>Android Studio enables access to Maven, JCenter, and Ivy repositories with the
+<code>repositories</code> block in the <code>build.gradle</code> as a shortcut to specifying
+the URL of the repository.
+
+<p>If there are required repositories not declared in the <code>build.gradle</code> file, first add
+the repository to the <code>repositories</code> block, and then declare the dependencies in a way
+that Maven, JCenter, or Ivy declare their artifacts. The following example shows how to add the
+Maven repository with the guava 11.0.2 dependency using the <code>mavenCentral()</code> property: </p>
+
+<pre>
+repositories {
+ mavenCentral()
+}
+
+android {
+ ...
+}
+
+dependencies {
+ compile 'com.google.guava:guava:11.0.2'
+ instrumentationtestCompile 'com.squareup.fast-android:1:0.4'
+}
+
+</pre>
+
+<p>The Android Studio project created during the import process can also re-use any
+dependencies on other components. These components can be external binary packages or other
+<a href="http://www.gradle.org">Gradle</a> projects. If a dependency has dependencies of its own,
+those dependencies are also included in the new Android Studio project. </p>
+
+
+<p class="note"><strong>Note:</strong> If there were references to Eclipse ADT workspace library
+files in the <code>project.properties</code> or <code>.classpath</code> files
+that were not imported from the Eclipse project, you can now add dependencies to these library files
+in the <code>build.gradle</code> file. For more information, see
+<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>. </p>
+
+
+<h3 id="scopes">Dependency and compilation scopes </h3>
+<p>Android Studio supports compilation scopes to customize which dependencies get
+included in each build, for example assigning different dependencies to different
+<a href="{@docRoot}tools/building/configuring-gradle.html#workBuildVariants"> build variants</a>.</p>
+
+<p>This list shows the Android Studio scope names and definitions: </p>
+
+<ul>
+ <li>compile - <code>compile</code> </li>
+ <li>run time - <code>package</code></li>
+ <li>testCompile - <code>AndroidTestCompile</code></li>
+ <li>testRuntime - <code>AndroidTestRunPackage</code></li>
+ <li>buildTypeCompile - <code>buildTypeCompile</code> </li>
+ <li>productFlavorCompile - <code>productFlavorCompile</code> </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Dependencies for library projects must be added with the
+<code>compile</code> scope. </p>
+
+
+<p>With the <a href="http://www.gradle.org">Gradle</a>-based DSL, you can also add custom
+dependency scopes, such as <code>betaCompile file('libs/protobug.jar')</code> to define a beta
+build dependency. </p>
+
+<p>The scope and compilation configuration in the build file determine the
+components compiled into the app, added to the compilation classpath, and packaged in the final
+APK file. Based on the dependency and compilation scope, different compilation configurations
+can be specified to include the dependencies and classpaths, for example: </p>
+
+<ul>
+<li><code>compile</code> - for the main application. </li>
+<li><code>androidTestCompile</code> - for the test application. </li>
+<li><code>debugCompile</code> - for the debug buildType application.</li>
+<li><code>releaseCompile</code> - for the release buildType application. </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Because it’s not possible to build an APK that does not
+have an associated <code>buildType</code>, the APK built from your app is always configured with
+at least two dependency and compile configurations: <code>compile</code> and
+<code>debugCompile</code>. </p>
+
+<p>Unlike Eclipse ADT, by default Android Studio does not compile your code when there are changes.
+Use the <strong>File > Settings > Build, Execution, Deployment Compiler</strong> option
+to enable automatic compilation. </p>
+
+
+
+<h2 id="build-process">Gradle-based Build Process </h2>
+<p>Android Studio imports the Eclipse ADT Ant-based
+build tasks and converts the tasks to <a href="http://www.gradle.org">Gradle</a>-based build tasks.
+These new build tasks include the
+main <code>assemble</code> task and at least two outputs based on the default build types:
+a <code>debug</code> APK and a
+<code>release</code> APK. Each of these build tasks has its own Android build system anchor task
+to facilitate building them independently: </p>
+<ul>
+ <li><code>assemble</code></li>
+ <li><code>assembleDebug</code></li>
+ <li><code>assembleRelease</code></li>
+</ul>
+
+<p>In Android Studio, you can view all the supported build tasks in the
+<em>Gradle</em> project tab. </p>
+
+<p>With the <a href="http://www.gradle.org">Gradle</a>-based build system, Android Studio uses a
+<a href="http://www.gradle.org">Gradle</a> wrapper to fully integrate the
+Android Plugin for Gradle. The Android Plugin for Gradle also
+runs independent of Android Studio. This means that with Android Studio build system your build
+output is always the same, whether you build your Android apps from Android Studio, from the
+command line on your machine, or on machines where Android Studio is not installed (such as
+continuous integration servers). </p>
+
+<p>Unlike Eclipse ADT with dependent plugin and build updates, the <code>build.gradle</code>
+files allow you to customize the build settings for each Android Studio module and build variant,
+so the build versions can be set independently, and are not dependent on the Android Studio
+or build tools versions. This makes it easy to maintain and build legacy apps along with your
+current app, using build variants to generate different APKs from the same app modules, but
+built with different build versions and build chains. </p>
+
+<p>For more details about the Android Studio build system, see
+<a href="{@docRoot}sdk/installing/studio-build.html">Build System Overview</a>.</p>
+
+<h3>Using the Android Studio build system's declarative logic </h3>
+<p>In contrast with the XML statements in Ant build files, the Android build system and
+<a href="http://www.gradle.org">Gradle</a> DSL provide a declarative build language so you can
+easily extend the Gradle-based build process beyond the typical XML build tasks. For example,
+this build file shows how to define a custom function to inject a dynamic <code>versionCode</code>
+in build outputs: </p>
+
+<pre>
+def getVersionCode) {
+ def code = …
+ return code
+}
+
+android {
+ defaultConfig {
+ versionCode getVersionCode()
+ …
+ }
+}
+</pre>
+
+<p>This example shows how to append <em>debug</em> to your package and version names used in the
+<code>debug</code> build variant of your app: </p>
+
+<pre>
+android {
+ buildTypes {
+ debug {
+ packageNameSuffix ‘.debug’
+ versionNameSuffix ‘-DEBUG’
+ }
+ beta {
+ …
+ }
+ }
+}
+</pre>
+
+
+<p>You can also use the declarative DSL in the Android build system to generate custom build
+versions, for example a debuggable version of your release APK. This examples adds the
+<code>debuggable true</code> property to the <code>release</code> build type in the
+<code>build.gradle</code> file to build an identical debuggable version of the release package. </p>
+
+<pre>
+android {
+ buildTypes {
+ debugRelease.initWith(buildTypes.release)
+ debugRelease {
+ debuggable true
+ packageNameSuffix '.debugrelease'
+ signingConfig signingConfigs.debug
+ }
+
+ }
+ sourceSets.debugRelease.setRoot('src/release')
+}
+</pre>
+
+
+
+
+
+
+<h2 id="debug-inspect">Debugging and Code Inspections</h2>
+<p>Using code inspection tools such as <a href="{@docRoot}tools/help/lint.html">lint</a> is a
+standard part of Android development. Android Studio extends
+<a href="{@docRoot}tools/help/lint.html">lint</a> support with additional
+<a href="{@docRoot}tools/help/lint.html">lint</a> checks and supports Android
+<a href="{@docRoot}tools/debugging/annotations.html">annotations</a> that
+allow you to help detect more subtle code problems, such as null pointer exceptions and resource
+type conflicts. Annotations are added as metadata tags that you attach to variables, parameters,
+and return values to inspect method return values, passed parameters, and local variables and
+fields. </p>
+
+<p>For more information on enabling <a href="{@docRoot}tools/help/lint.html">lint</a> inspections
+and running <a href="{@docRoot}tools/help/lint.html">lint</a>,
+see <a href="{@docRoot}tools/debugging/improving-w-lint.html">Improving Your Code with lint</a>.
+For more information about using annotations, see
+<a href="{@docRoot}tools/debugging/annotations.html#annotations">Improving your Code with
+Annotations</a>. </p>
+
+<p>In addition to code inspection, Android Studio provides an integrated
+<a href="{@docRoot}tools/studio/index.html#mem-cpu">memory and CPU monitor</a> view so you
+can more easily monitor your app's performance and memory usage to track CPU usage, find
+deallocated objects, locate memory leaks, and track the amount of memory the connected device is
+using. </p>
+
+
+
+<h2 id="resource-optimization">Resource Optimization </h2>
+<p>After importing and building your app, Android Studio supports several
+<a href="http://www.gradle.org">Gradle</a>-based properties to help you minimize your app's
+resource utilization. </p>
+
+
+<h3>Resource shrinking</h3>
+<p>In Android Studio, resource shrinking enables the automatic removal of unused resources from
+your packaged app and also removes resources from library dependencies if the resources are not
+actually used by your app.</p>
+
+<p>Use the <code>shrinkResources</code> attribute in the <code>buildType</code> block in your
+<code>build.gradle</code> file to enable resource shrinking. For example, if your application is
+using <a href="{@docRoot}google/play-services/index.html">Google Play services</a>
+to access Google Drive functionality, and you are not currently using
+<a href="{@docRoot}google/play-services/plus.html">Google+ Sign In</a>, then
+this setting removes the various drawable assets for the <code>SignInButton</code> buttons. </p>
+
+<p class="note"><strong>Note:</strong> Resource shrinking works in conjunction with code shrinking
+tools, such as <a href="{@docRoot}tools/help/proguard.html">ProGuard</a>. </p>
+
+<p>To enable resource shrinking, update the <code>buildTypes</code> block in the
+<code>build.gradle</code> file to include <code>minifyEnabled true</code>,
+<code>shrinkResources true</code>, and <code>proguardFiles</code> settings as shown in the
+following example <a href="http://www.gradle.org">Gradle</a> build file.</p>
+
+<pre>
+android {
+ ...
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'),
+ 'proguard-rules.pro'
+ }
+ }
+}
+</pre>
+
+
+
+<h3>Filtering language resources</h3>
+<p>Use the <code>resConfig</code> attribute in your <code>build.gradle</code> file
+to filter the locale resources included in your packaged app. This filtering can be especially
+useful when library dependencies such as <code>appcompat-v7</code> and other libraries such as
+<code>google-play-services_lib</code> are included in your app. </p>
+
+<p>The following example limits the locale resources to three language settings: <code>en</code>,
+<code>de</code>, and <code>es</code>:</p>
+
+<pre>
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ resConfigs "en", "de", "es" //Define the included language resources.
+ }
+...
+
+</pre>
+
+
+
+<h4>Filtering bundled resources</h4>
+<p>You can also use the <code>resConfig</code> build setting to limit the bundled resources
+in any resource folder. For example, you could also add <code>resConfigs</code>
+settings for density folders, such as <code>mdpi</code> or <code>hdpi</code> to limit the drawable
+resources that are packaged in your <code>APK</code> file. This example limits the app's
+bundled resources to medium-density (MDPI) and high-density (HDPI) resources. </p>
+
+<pre>
+android {
+ defaultConfig {
+ ...
+ resConfigs "mdpi", "hdpi"
+ }
+}
+</pre>
+
+For more information about screen and resource densities, see
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>
+and <a href="{@docRoot}training/multiscreen/screendensities.html">Supporting Different Densities</a>.
+
+
+<h3>Resource merging </h3>
+<p>With Android Studio, identical resources, such as copies of launcher and menu icons, may end up
+in different resource folders throughout your app. To reduce resource duplication and improve
+the performance of your app, Android Studio merges resources with an identical resource name, type,
+and qualifier into a single resource and passes the single, merged resource to the Android Asset
+Packaging Tool (AAPT) for distribution in the APK file. </p>
+
+<p>The resource merging process looks for identical resources in the following <code>/res/</code>
+folders: </p>
+<ul>
+ <li>AAR bundles of library project dependencies</li>
+ <li><code>src/main/</code> </li>
+ <li><code>src/<em>productFlavor</em>/</code> </li>
+ <li><code>src/<em>buildType</em>/</code> </li>
+</ul>
+
+<p>Identical resources are merged in the following low to high priority order: </p>
+<pre>
+dependencies --> src/main/ --> src/productFlavor/ --> src/buildType/
+</pre>
+
+<p>For example, if the <code>res/ic_menu.png</code> file is included in both the
+<code>src/main/res/</code> and <code>src/productFlavor/res/</code> folders, the resources are merged
+so only the file with the higher priority, in this case the <code>src/productFlavor/res/</code>
+file, is included in the APK file. </p>
+
+<p class="note"><strong>Note:</strong> Identical resources in the same source set are not merged
+and instead generate a resource merge error. This can happen if the <code>sourceSet</code> property
+in the <code>build.gradle</code> file is used to define multiple source sets, for example
+<code>src/main/res/</code> and <code>src/main/res2/</code>, and these folders contain identical
+resources. </p>
+
+
+
+
+<h2 id="signing">App Signing and ProGuard </h2>
+<p>Based on the imported Eclipse ADT app settings, Android Studio automatically sets up your app
+signing and maintains any ProGuard settings. </p>
+
+<h3>App Signing</h3>
+<p>If your app used a debug certificate in Eclipse ADT, Android Studio continues to reference that
+certificate. Otherwise, the <code>debug</code> configuration uses the Android Studio generated
+debug keystore, with a known password and a default key with a known password located in
+<code>$HOME/.android/debug.keystore</code>. The <code>debug</code> build type is set to use this
+debug <code>SigningConfig</code> automatically when you run or debug your project
+from Android Studio. </p>
+
+<p>In release mode, Android Studio applies the release certificate used in Eclipse ADT. If no
+release certificate was located during the import process, add the release signing configuration to
+the <code>build.gradle</code> file or use the <strong> Build > Generate Signed APK</strong> menu
+option to open the Generate Signed APK Wizard. For more information about signing your app, see
+<a href="{@docRoot}tools/publishing/app-signing.html">Signing Your Applications</a>. </p>
+
+
+<h3>ProGuard</h3>
+<p>If the <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> option is specified in the
+<code>project.properties</code> file in the Eclipse ADT project, Android Studio imports the
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> files and adds the
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> settings to the
+<code>build.gradle</code> file. <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> is
+supported through the <code>minifyEnabled</code> property as shown in this example. </p>
+
+<pre>
+android {
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFile getDefaultProguardFile('proguard-android.txt')
+ }
+ }
+
+ productFlavors {
+ flavor1 {
+ }
+ flavor2 {
+ proguardFile 'some-other-rules.txt'
+ }
+ }
+}
+
+</pre></p>
+
+
+
+
+<h2 id="support-lib">Android Support Repository and Google Play services Repository</h2>
+<p>While Eclipse ADT uses the Android <a href="{@docRoot}tools/support-library/index.html">Support
+Library</a> and Google Play services Library, Android Studio replaces these libraries during the
+import process with the Android Support Repository and Google Repository to maintain
+compatible functionality and support new Android features. Android Studio adds these dependencies
+as Maven dependencies using the known Maven coordinates, so these dependencies do not require
+manual updates. </p>
+
+<p>In Eclipse, in order to use a
+<a href="{@docRoot}tools/support-library/index.html">Support Library</a>, you must modify your
+project's classpath dependencies within your development environment for each
+<a href="{@docRoot}tools/support-library/index.html">Support Library</a> you want to use. In
+Android Studio, you no longer need to copy library sources into your
+own projects, you can simply declare a dependency and the library is automatically downloaded and
+merged into your project. This includes automatically merging in resources, manifest entries,
+<a href="{@docRoot}tools/help/proguard.html">ProGuard</a> exclusion rules, and custom lint rules
+at build time. </p>
+
+<p>Android Studio also supports binary library Android ARchives (AARs). AARs are a library project's
+main output as a combination of compiled code (as a jar file and/or native .so files) and
+resources (manifest, res, assets). <p/>
+
+
+<h2 id="app-package">App Packaging</h2>
+<p>The Android build system introduces the use of the <code>applicationId</code> attribute to
+uniquely identify application packages for publishing. The application ID is set in the
+<code>android</code> section of the <code>build.gradle</code> file. </p>
+
+<p>The <code>applicationId</code> is specified only in your <code>build.gradle</code> file, and
+not in the
+<code>AndroidManifest.xml</code> file. The Gradle-based build system enables you
+to uniquely identify different packages for each build variant based on product flavors and build
+types. You can also add the <code>applicationIdSuffix</code> property to the build type in the
+<code>build.gradle</code> file to append an identifier, such as '.debug', to the application ID
+generated for each product flavor. </p>
+
+
+
+<h2 id="software-updates">Software Updates</h2>
+<p>Android Studio provides several levels of update and maintenance to help you keep Android Studio
+up-to-date based on your code-level preference: </p>
+
+<ul>
+ <li><strong>Canary channel</strong>: Canary builds provide bleeding edge releases and are updated
+ about weekly. These builds do get tested, but are still subject to bugs, as these are
+ early releases. This is not recommended for production.</li>
+ <li><strong>Dev channel</strong>: Dev builds are canary builds that passed initial testing and
+ usage. They are updated roughly bi-weekly or monthly.</li>
+ <li><strong>Beta channel</strong>: Beta builds provide beta-quality releases for final testing
+ and feedback before a production release.</li>
+ <li><strong>Stable channel</strong>: Stable builds provide stable, production-ready release
+ versions.</li>
+</ul>
+
+
+
+<h2 id="version-control">Version Control </h2>
+<p>Eclipse ADT supports version control through the use of plugins, such as the EGit and Subversive
+plug-ins. </p>
+
+<p>Android Studio supports a variety of version control systems (Git, GitHub, CVS, Mercurial,
+Subversion, and Google Cloud) so version control operations can continue from within Android
+Studio. </p>
+
+<p>After importing your Eclipse ADT app into Android Studio, use the
+Android Studio <em>VCS</em> menu options to enable VCS support for the desired version control
+system, create a repository, import the new files into version control, and perform other version
+control operations. </p>
+
+<p class="note"><strong>Note:</strong> You can also use the
+<strong>File > Setting > Version Control</strong> menu option to setup and modify the version
+control settings. </p>
+
+<h3>Files to ignore </h3>
+<p>A number of Android Studio files are typically not added to version control as these are
+temporary files or files that get overwritten with each build. These files are listed in
+an exclusion file, such as <code>.gitignore</code>, for the project and each app module.
+Typically, the following files are excluded from version control: </p>
+
+<ul>
+ <li>.gradle </li>
+ <li>/local.properties </li>
+ <li>/.idea/workspace.xml </li>
+ <li>/.idea/libraries </li>
+ <li>.DS_Store</li>
+ <li>/build </li>
+ <li>/captures </li>
+</ul>
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 0113347..fa6d987 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -175,7 +175,7 @@
<a href="{@docRoot}tools/building/configuring-gradle.html">Configuring Gradle Builds</a>.</p>
-<h3>Application ID for package identification </h3>
+<h3 id="app-id">Application ID for package identification </h3>
<p>With the Android build system, the <em>applicationId</em> attribute is used to
uniquely identify application packages for publishing. The application ID is set in the
<em>android</em> section of the <code>build.gradle</code> file.
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 82515d4..abfa030 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -189,71 +189,13 @@
<span class="en">Configuring Gradle Builds</span></a></li>
<li><a href="<?cs var:toroot ?>tools/building/plugin-for-gradle.html">
<span class="en">Android Plugin for Gradle</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/manifest-merge.html">
+ <span class="en">Manifest Merging</span></a></li>
<li><a href="<?cs var:toroot ?>tools/building/multidex.html">
<span class="en">Apps Over 65K Methods</span></a></li>
</ul>
</li><!-- end of build system -->
-<!-- Performance Tools menu-->
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>tools/performance/index.html">Peformance Tools</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/performance/debug-gpu-overdraw/index.html">
- Overdraw Debugger</a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/profile-gpu-rendering/index.html">
- Rendering Profiler</a>
- </li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>tools/performance/hierarchy-viewer/index.html">
- Hierarchy Viewer</a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/performance/hierarchy-viewer/setup.html"><span
- class="en">Setup</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/hierarchy-viewer/profiling.html"><span
- class="en">Profiling</span></a>
- </li>
- </ul>
- </li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>tools/performance/comparison.html">
- Memory Profilers</a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/performance/memory-monitor/index.html"><span
- class="en">Memory Monitor</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/heap-viewer/index.html"><span
- class="en">Heap Viewer</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/allocation-tracker/index.html"><span
- class="en">Allocation Tracker</span></a>
- </li>
- </ul>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/traceview/index.html">
- Traceview</a>
- </li>
- <li><a href="<?cs var:toroot ?>tools/performance/systrace/index.html">
- Systrace</a>
- </li>
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>tools/performance/batterystats-battery-historian/index.html">
- Battery Profilers</a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/performance/batterystats-battery-historian/charts.html"><span
- class="en">Historian Charts</span></a>
- </li>
- </ul>
- </li>
- </ul>
- </li><!-- End Performance Tools menu-->
-
<!-- Testing Tools menu-->
<li class="nav-section">
@@ -351,7 +293,15 @@
<span class="en">Eclipse with ADT</span></a>
</div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/installing/migrate.html">Migrating to Android Studio</a></li>
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>sdk/installing/migrate.html">
+ <span class="en">Migrating to Android Studio</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>tools/studio/eclipse-transition-guide.html">
+ Transition Guide</span></a> </li>
+ </ul>
+ </li>
+
<li><a href="<?cs var:toroot ?>sdk/installing/installing-adt.html">
<span class="en">Installing the Eclipse Plugin</span></a></li>
<li><a href="<?cs var:toroot ?>tools/projects/projects-eclipse.html">Managing Projects</a></li>
diff --git a/docs/html/training/enterprise/app-compatibility.jd b/docs/html/training/enterprise/app-compatibility.jd
index 216a799..419ba89 100644
--- a/docs/html/training/enterprise/app-compatibility.jd
+++ b/docs/html/training/enterprise/app-compatibility.jd
@@ -250,14 +250,14 @@
support the <code>--user</code> flag, which lets you specify which user to run
as. By specifying a user, you can choose whether to run as the unmanaged or
managed profile. For
-more information, see <a href="{@docRoot}tools/help/adb.html#am">Android Debug
-Bridge: Using activity manager (am)</a>.</li>
+more information, see <a href="{@docRoot}tools/help/shell.html#am">ADB
+Shell Commands</a>.</li>
<li>To find the active users on a device, use the adb package manager's
<code>list users</code> command. The first number in the output string is the
user ID, which you can use with the <code>--user</code> flag. For more
-information, see <a href="{@docRoot}tools/help/adb.html#pm">Android Debug
-Bridge: Using package manager (pm)</a>.</li>
+information, see <a href="{@docRoot}tools/help/shell.html#pm">ADB Shell
+Commands</a>.</li>
</ul>
diff --git a/docs/html/training/tv/discovery/recommendations.jd b/docs/html/training/tv/discovery/recommendations.jd
index a74ee56..ffe33f2 100644
--- a/docs/html/training/tv/discovery/recommendations.jd
+++ b/docs/html/training/tv/discovery/recommendations.jd
@@ -10,6 +10,7 @@
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
+ <li><a href="#best-practices">Best Practices for Recommendations</a></li>
<li><a href="#service">Create a Recommendations Service</a></li>
<li><a href="#build">Build Recommendations</a></li>
<li><a href="#run-service">Run Recommendations Service</a></li>
@@ -47,6 +48,46 @@
Leanback sample app</a>.
</p>
+<h2 id="best-practices">Best Practices for Recommendations</h2>
+
+<p>Recommendations help users quickly find the content and apps they enjoy. Creating
+recommendations that are high-quality and relevant to users is an important factor in creating a
+great user experience with your TV app. For this reason, you should carefully consider what
+recommendations you present to the user and manage them closely.</p>
+
+<h3 id="types">Types of Recommendations</h3>
+
+<p>When you create recommendations, you should link users back to incomplete viewing activities or
+suggest activities that extend that to related content. Here are some specific type of
+recommendations you should consider:</p>
+
+<ul>
+<li><strong>Continuation content</strong> recommendations for the next episode for users to resume
+watching a series.</li>
+<li><strong>New content</strong> recommendations, such as for a new first-run episode, if the user
+finished watching another series.
+<li><strong>Related content</strong> recommendations based on the users historic viewing behavior.
+</ul>
+
+<p>For more information on how to design recommendation cards for the best user experience, see
+<a href="https://www.google.com/design/spec-tv/system-overview/recommendation-row.html#recommendation-row-types-of-recommendations"
+class="external-link">Recommendation Row</a> in the Android TV Design Spec.</p>
+
+<h3 id="refreshing">Refreshing Recommendations</h3>
+
+<p>When refreshing recommendations, don't just remove and repost them, because doing so causes
+the recommendations to appear at the end of the recommendations row. Once a content item, such as a
+movie, has been played, <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Removing">
+remove it</a> from the recommendations.</p>
+
+<h3 id="customization">Customizing Recommendations</h3>
+
+<p>You can customize recommendation cards to convey branding information, by setting user interface
+elements such as the card's foreground and background image, color, app icon, title, and subtitle.
+To learn more, see
+<a href="https://www.google.com/design/spec-tv/system-overview/recommendation-row.html#recommendation-row-card-customization"
+class="external-link">Recommendation Row</a> in the Android TV Design Spec.</p>
+
<h2 id="service">Create a Recommendations Service</h2>
@@ -116,8 +157,8 @@
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(DetailsActivity.class);
stackBuilder.addNextIntent(detailsIntent);
- // Ensure a unique PendingIntents, otherwise all recommendations end up with the same
- // PendingIntent
+ // Ensure a unique PendingIntents, otherwise all
+ // recommendations end up with the same PendingIntent
detailsIntent.setAction(Long.toString(movie.getId()));
PendingIntent intent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -143,19 +184,6 @@
</manifest>
</pre>
-<h3 id="refreshing">Refreshing Recommendations</h3>
-
-<p>Base your recommendations on user behavior and data such as play lists, wish lists, and associated
-content. When refreshing recommendations, don't just remove and repost them, because doing so causes
-the recommendations to appear at the end of the recommendations row. Once a content item, such as a
-movie, has been played, <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Removing">
-remove it</a> from the recommendations.</p>
-
-<p>The order of an app's recommendations is preserved according to the order in which the app
-provides them. The framework interleaves app recommendations based on recommendation quality,
-as measured by user behavior. Better recommendations make an app's recommendations more likely
-to appear near the front of the list.</p>
-
<h2 id="build">Build Recommendations</h2>
<p>
diff --git a/docs/html/training/volley/requestqueue.jd b/docs/html/training/volley/requestqueue.jd
index 5e892bf..6d19cee 100644
--- a/docs/html/training/volley/requestqueue.jd
+++ b/docs/html/training/volley/requestqueue.jd
@@ -139,7 +139,8 @@
<p>Here is an example of a singleton class that provides {@code RequestQueue} and
{@code ImageLoader} functionality:</p>
-<pre>private static MySingleton mInstance;
+<pre>public class MySingleton {
+ private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
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/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index dcccf35..2bbbff3 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -67,4 +67,38 @@
*/
public final int nativeInt;
}
+
+ /**
+ * @hide
+ */
+ public static final int modeToInt(Mode mode) {
+ return mode.nativeInt;
+ }
+
+ /**
+ * @hide
+ */
+ public static final Mode intToMode(int val) {
+ switch (val) {
+ default:
+ case 0: return Mode.CLEAR;
+ case 1: return Mode.SRC;
+ case 2: return Mode.DST;
+ case 3: return Mode.SRC_OVER;
+ case 4: return Mode.DST_OVER;
+ case 5: return Mode.SRC_IN;
+ case 6: return Mode.DST_IN;
+ case 7: return Mode.SRC_OUT;
+ case 8: return Mode.DST_OUT;
+ case 9: return Mode.SRC_ATOP;
+ case 10: return Mode.DST_ATOP;
+ case 11: return Mode.XOR;
+ case 16: return Mode.DARKEN;
+ case 17: return Mode.LIGHTEN;
+ case 13: return Mode.MULTIPLY;
+ case 14: return Mode.SCREEN;
+ case 12: return Mode.ADD;
+ case 15: return Mode.OVERLAY;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 2c603e2..e235a99 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -575,7 +575,7 @@
}
}
- private void mutate() {
+ void mutate() {
mTransitions = mTransitions.clone();
mStateIds = mStateIds.clone();
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 1ae10d3..1857345 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -170,7 +170,7 @@
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
mAnimatedVectorState = new AnimatedVectorDrawableState(
- mAnimatedVectorState, mCallback, null);
+ mAnimatedVectorState, mCallback, mRes);
mMutated = true;
}
return this;
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 6090cf0..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() {
@@ -433,7 +432,7 @@
/**
* Set the layout direction for this drawable. Should be a resolved
- * layout direction, as the Drawable as no capacity to do the resolution on
+ * layout direction, as the Drawable has no capacity to do the resolution on
* its own.
*
* @param layoutDirection the resolved layout direction for the drawable,
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1759f53..1915dd7 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;
@@ -735,7 +730,7 @@
if (origDf != null) {
mDrawableFutures = origDf.clone();
} else {
- mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
+ mDrawableFutures = new SparseArray<>(mNumChildren);
}
// Create futures for drawables with constant states. If a
@@ -828,6 +823,9 @@
final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
mDrawables[index] = prepared;
mDrawableFutures.removeAt(keyIndex);
+ if (mDrawableFutures.size() == 0) {
+ mDrawableFutures = null;
+ }
return prepared;
}
}
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 85db6a1..7c9b30b 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -16,13 +16,16 @@
package android.graphics.drawable;
+import android.annotation.ColorInt;
import android.annotation.DrawableRes;
+import android.content.res.ColorStateList;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
@@ -67,6 +70,10 @@
private final int mType;
+ private ColorStateList mTintList;
+ static final PorterDuff.Mode DEFAULT_TINT_MODE = Drawable.DEFAULT_TINT_MODE; // SRC_IN
+ private PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+
// To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
// based on the value of mType.
@@ -109,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
@@ -254,6 +265,19 @@
* @return A fresh instance of a drawable for this image, yours to keep.
*/
public Drawable loadDrawable(Context context) {
+ final Drawable result = loadDrawableInner(context);
+ if (result != null && (mTintList != null || mTintMode != DEFAULT_TINT_MODE)) {
+ result.mutate();
+ result.setTintList(mTintList);
+ result.setTintMode(mTintMode);
+ }
+ return result;
+ }
+
+ /**
+ * Do the heavy lifting of loading the drawable, but stop short of applying any tint.
+ */
+ private Drawable loadDrawableInner(Context context) {
switch (mType) {
case TYPE_BITMAP:
return new BitmapDrawable(context.getResources(), getBitmap());
@@ -347,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.
@@ -466,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;
}
@@ -518,6 +552,38 @@
}
/**
+ * Store a color to use whenever this Icon is drawn.
+ *
+ * @param tint a color, as in {@link Drawable#setTint(int)}
+ * @return this same object, for use in chained construction
+ */
+ public Icon setTint(@ColorInt int tint) {
+ return setTintList(ColorStateList.valueOf(tint));
+ }
+
+ /**
+ * Store a color to use whenever this Icon is drawn.
+ *
+ * @param tintList as in {@link Drawable#setTintList(ColorStateList)}, null to remove tint
+ * @return this same object, for use in chained construction
+ */
+ public Icon setTintList(ColorStateList tintList) {
+ mTintList = tintList;
+ return this;
+ }
+
+ /**
+ * Store a blending mode to use whenever this Icon is drawn.
+ *
+ * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
+ * @return this same object, for use in chained construction
+ */
+ public Icon setTintMode(PorterDuff.Mode mode) {
+ mTintMode = mode;
+ return this;
+ }
+
+ /**
* Create an Icon pointing to an image file specified by path.
*
* @param path A path to a file that contains compressed bitmap data of
@@ -558,6 +624,15 @@
sb.append(" uri=").append(getUriString());
break;
}
+ if (mTintList != null) {
+ sb.append(" tint=");
+ String sep = "";
+ for (int c : mTintList.getColors()) {
+ sb.append(String.format("%s0x%08x", sep, c));
+ sep = "|";
+ }
+ }
+ if (mTintMode != DEFAULT_TINT_MODE) sb.append(" mode=").append(mTintMode);
sb.append(")");
return sb.toString();
}
@@ -603,31 +678,39 @@
throw new RuntimeException("invalid "
+ this.getClass().getSimpleName() + " type in parcel: " + mType);
}
+ if (in.readInt() == 1) {
+ mTintList = ColorStateList.CREATOR.createFromParcel(in);
+ }
+ mTintMode = PorterDuff.intToMode(in.readInt());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mType);
switch (mType) {
case TYPE_BITMAP:
final Bitmap bits = getBitmap();
- dest.writeInt(TYPE_BITMAP);
getBitmap().writeToParcel(dest, flags);
break;
case TYPE_RESOURCE:
- dest.writeInt(TYPE_RESOURCE);
dest.writeString(getResPackage());
dest.writeInt(getResId());
break;
case TYPE_DATA:
- dest.writeInt(TYPE_DATA);
dest.writeInt(getDataLength());
dest.writeBlob(getDataBytes(), getDataOffset(), getDataLength());
break;
case TYPE_URI:
- dest.writeInt(TYPE_URI);
dest.writeString(getUriString());
break;
}
+ if (mTintList == null) {
+ dest.writeInt(0);
+ } else {
+ dest.writeInt(1);
+ mTintList.writeToParcel(dest, flags);
+ }
+ dest.writeInt(PorterDuff.modeToInt(mTintMode));
}
public static final Parcelable.Creator<Icon> CREATOR
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 90891f6..d9469d4 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -133,6 +133,7 @@
mLayerState.mChildren = r;
ensurePadding();
+ refreshPadding();
}
LayerDrawable() {
@@ -143,6 +144,7 @@
mLayerState = createConstantState(state, res);
if (mLayerState.mNum > 0) {
ensurePadding();
+ refreshPadding();
}
}
@@ -162,6 +164,7 @@
inflateLayers(r, parser, attrs, theme);
ensurePadding();
+ refreshPadding();
}
/**
@@ -431,6 +434,7 @@
final ChildDrawable layer = createLayer(dr);
final int index = addLayer(layer);
ensurePadding();
+ refreshChildPadding(index, layer);
return index;
}
@@ -568,6 +572,8 @@
childDrawable.mDrawable = drawable;
mLayerState.invalidateCache();
+
+ refreshChildPadding(index, childDrawable);
}
/**
@@ -1248,16 +1254,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;
@@ -1633,6 +1629,14 @@
mPaddingB = new int[N];
}
+ void refreshPadding() {
+ final int N = mLayerState.mNum;
+ final ChildDrawable[] array = mLayerState.mChildren;
+ for (int i = 0; i < N; i++) {
+ refreshChildPadding(i, array[i]);
+ }
+ }
+
@Override
public ConstantState getConstantState() {
if (mLayerState.canConstantState()) {
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/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 134451b..bf069d3 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -198,6 +198,7 @@
setColor(color);
ensurePadding();
+ refreshPadding();
updateLocalState();
}
@@ -423,6 +424,7 @@
if (super.setDrawableByLayerId(id, drawable)) {
if (id == R.id.mask) {
mMask = drawable;
+ mHasValidMask = false;
}
return true;
@@ -1012,6 +1014,7 @@
if (mState.mNum > 0) {
ensurePadding();
+ refreshPadding();
}
if (res != null) {
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/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index c83af11..758410a 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -59,22 +59,10 @@
* @attr ref android.R.styleable#DrawableStates_state_pressed
*/
public class StateListDrawable extends DrawableContainer {
- private static final String TAG = StateListDrawable.class.getSimpleName();
+ private static final String TAG = "StateListDrawable";
private static final boolean DEBUG = false;
- /**
- * To be proper, we should have a getter for dither (and alpha, etc.)
- * so that proxy classes like this can save/restore their delegates'
- * values, but we don't have getters. Since we do have setters
- * (e.g. setDither), which this proxy forwards on, we have to have some
- * default/initial setting.
- *
- * The initial setting for dither is now true, since it almost always seems
- * to improve the quality at negligible cost.
- */
- private static final boolean DEFAULT_DITHER = true;
-
private StateListState mStateListState;
private boolean mMutated;
@@ -104,16 +92,16 @@
@Override
protected boolean onStateChange(int[] stateSet) {
+ final boolean changed = super.onStateChange(stateSet);
+
int idx = mStateListState.indexOfStateSet(stateSet);
if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
+ Arrays.toString(stateSet) + " found " + idx);
if (idx < 0) {
idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
}
- if (selectDrawable(idx)) {
- return true;
- }
- return super.onStateChange(stateSet);
+
+ return selectDrawable(idx) || changed;
}
@Override
@@ -326,13 +314,14 @@
}
}
- private void mutate() {
+ void mutate() {
mThemeAttrs = mThemeAttrs != null ? mThemeAttrs.clone() : null;
final int[][] stateSets = new int[mStateSets.length][];
for (int i = mStateSets.length - 1; i >= 0; i--) {
stateSets[i] = mStateSets[i] != null ? mStateSets[i].clone() : null;
}
+ mStateSets = stateSets;
}
int addStateSet(int[] stateSet, Drawable drawable) {
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 5e205bd..24cb055 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -15,6 +15,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -31,10 +32,10 @@
import android.graphics.PixelFormat;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.PorterDuff.Mode;
import android.util.ArrayMap;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.LayoutDirection;
import android.util.Log;
import android.util.MathUtils;
@@ -212,13 +213,24 @@
// caching the bitmap by default is allowed.
private boolean mAllowCaching = true;
+ // Given the virtual display setup, the dpi can be different than the inflation's dpi.
+ // Therefore, we need to scale the values we got from the getDimension*().
+ private int mDpiScaledWidth = 0;
+ private int mDpiScaledHeight = 0;
+ private Insets mDpiScaleInsets = Insets.NONE;
+
public VectorDrawable() {
- mVectorState = new VectorDrawableState();
+ this(null, null);
}
- private VectorDrawable(@NonNull VectorDrawableState state) {
- mVectorState = state;
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ private VectorDrawable(@NonNull VectorDrawableState state, @Nullable Resources res) {
+ if (state == null) {
+ mVectorState = new VectorDrawableState();
+ } else {
+ mVectorState = state;
+ mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ }
+ updateDimensionInfo(res, false);
}
@Override
@@ -359,18 +371,66 @@
@Override
public int getIntrinsicWidth() {
- return (int) mVectorState.mVPathRenderer.mBaseWidth;
+ return mDpiScaledWidth;
}
@Override
public int getIntrinsicHeight() {
- return (int) mVectorState.mVPathRenderer.mBaseHeight;
+ return mDpiScaledHeight;
}
/** @hide */
@Override
public Insets getOpticalInsets() {
- return mVectorState.mVPathRenderer.mOpticalInsets;
+ return mDpiScaleInsets;
+ }
+
+ /*
+ * Update the VectorDrawable dimension since the res can be in different Dpi now.
+ * Basically, when a new instance is created or getDimension() is called, we should update
+ * the current VectorDrawable's dimension information.
+ * Only after updateStateFromTypedArray() is called, we should called this and update the
+ * constant state's dpi info, i.e. updateConstantStateDensity == true.
+ */
+ void updateDimensionInfo(@Nullable Resources res, boolean updateConstantStateDensity) {
+ if (res != null) {
+ final int densityDpi = res.getDisplayMetrics().densityDpi;
+ final int targetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
+
+ if (updateConstantStateDensity) {
+ mVectorState.mVPathRenderer.mTargetDensity = targetDensity;
+ } else {
+ final int constantStateDensity = mVectorState.mVPathRenderer.mTargetDensity;
+ if (targetDensity != constantStateDensity && constantStateDensity != 0) {
+ mDpiScaledWidth = Bitmap.scaleFromDensity(
+ (int) mVectorState.mVPathRenderer.mBaseWidth, constantStateDensity,
+ targetDensity);
+ mDpiScaledHeight = Bitmap.scaleFromDensity(
+ (int) mVectorState.mVPathRenderer.mBaseHeight,constantStateDensity,
+ targetDensity);
+ final int left = Bitmap.scaleFromDensity(
+ mVectorState.mVPathRenderer.mOpticalInsets.left, constantStateDensity,
+ targetDensity);
+ final int right = Bitmap.scaleFromDensity(
+ mVectorState.mVPathRenderer.mOpticalInsets.right, constantStateDensity,
+ targetDensity);
+ final int top = Bitmap.scaleFromDensity(
+ mVectorState.mVPathRenderer.mOpticalInsets.top, constantStateDensity,
+ targetDensity);
+ final int bottom = Bitmap.scaleFromDensity(
+ mVectorState.mVPathRenderer.mOpticalInsets.bottom, constantStateDensity,
+ targetDensity);
+ mDpiScaleInsets = Insets.of(left, top, right, bottom);
+ return;
+ }
+ }
+ }
+ // For all the other cases, like either res is null, constant state is not initialized or
+ // target density is the same as the constant state, we will just use the constant state
+ // dimensions.
+ mDpiScaledWidth = (int) mVectorState.mVPathRenderer.mBaseWidth;
+ mDpiScaledHeight = (int) mVectorState.mVPathRenderer.mBaseHeight;
+ mDpiScaleInsets = mVectorState.mVPathRenderer.mOpticalInsets;
}
@Override
@@ -393,6 +453,7 @@
try {
state.mCacheDirty = true;
updateStateFromTypedArray(a);
+ updateDimensionInfo(t.getResources(), true /* update constant state */);
} catch (XmlPullParserException e) {
throw new RuntimeException(e);
} finally {
@@ -485,6 +546,7 @@
inflateInternal(res, parser, attrs, theme);
mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ updateDimensionInfo(res, true /* update constant state */);
}
private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
@@ -687,7 +749,6 @@
int mCachedRootAlpha;
boolean mCachedAutoMirrored;
boolean mCacheDirty;
-
/** Temporary paint object used to draw cached bitmaps. */
Paint mTempPaint;
@@ -797,12 +858,12 @@
@Override
public Drawable newDrawable() {
- return new VectorDrawable(this);
+ return new VectorDrawable(this, null);
}
@Override
public Drawable newDrawable(Resources res) {
- return new VectorDrawable(this);
+ return new VectorDrawable(this, res);
}
@Override
@@ -847,6 +908,8 @@
int mRootAlpha = 0xFF;
String mRootName = null;
+ int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+
final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
public VPathRenderer() {
@@ -886,6 +949,7 @@
mChangingConfigurations = copy.mChangingConfigurations;
mRootAlpha = copy.mRootAlpha;
mRootName = copy.mRootName;
+ mTargetDensity = copy.mTargetDensity;
if (copy.mRootName != null) {
mVGTargetsMap.put(copy.mRootName, this);
}
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
index 1410d87..7680342 100644
--- a/include/androidfw/ZipFileRO.h
+++ b/include/androidfw/ZipFileRO.h
@@ -91,6 +91,7 @@
* a matching call to endIteration with the same cookie.
*/
bool startIteration(void** cookie);
+ bool startIteration(void** cookie, const char* prefix, const char* suffix);
/**
* Return the next entry in iteration order, or NULL if there are no more
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 6a08368..98b44dc 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -40,6 +40,7 @@
import android.security.keystore.UserNotAuthenticatedException;
import android.util.Log;
+import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.util.List;
import java.util.Locale;
@@ -663,14 +664,14 @@
"Failed to obtained key characteristics",
getKeyStoreException(getKeyCharacteristicsErrorCode));
}
- List<Long> keySids =
- keyCharacteristics.getLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
+ List<BigInteger> keySids =
+ keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
if (keySids.isEmpty()) {
// Key is not bound to any SIDs -- no amount of authentication will help here.
return new KeyPermanentlyInvalidatedException();
}
long rootSid = GateKeeper.getSecureUserId();
- if ((rootSid != 0) && (keySids.contains(Long.valueOf(rootSid)))) {
+ if ((rootSid != 0) && (keySids.contains(KeymasterArguments.toUint64(rootSid)))) {
// One of the key's SIDs is the current root SID -- user can be authenticated
// against that SID.
return new UserNotAuthenticatedException();
@@ -678,7 +679,7 @@
long fingerprintOnlySid = getFingerprintOnlySid();
if ((fingerprintOnlySid != 0)
- && (keySids.contains(Long.valueOf(fingerprintOnlySid)))) {
+ && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) {
// One of the key's SIDs is the current fingerprint SID -- user can be
// authenticated against that SID.
return new UserNotAuthenticatedException();
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
index f412743..6411066 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -207,7 +207,7 @@
protected final void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
+ keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
}
protected final int getTagLengthBits() {
@@ -288,11 +288,11 @@
+ " practices.");
}
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
if (mIv != null) {
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_NONCE, mIv);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
}
}
@@ -302,7 +302,7 @@
mIvHasBeenUsed = true;
// NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBlob(KeymasterDefs.KM_TAG_NONCE, null);
+ byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
if ((returnedIv != null) && (returnedIv.length == 0)) {
returnedIv = null;
}
@@ -363,8 +363,9 @@
@Override
public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
- byte[] additionalEntropy) throws KeyStoreException {
- byte[] output = mDelegate.doFinal(input, inputOffset, inputLength, additionalEntropy);
+ byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
+ byte[] output = mDelegate.doFinal(input, inputOffset, inputLength, signature,
+ additionalEntropy);
if (output != null) {
try {
mBufferedOutput.write(output);
@@ -406,7 +407,7 @@
@Override
public OperationResult update(byte[] input) {
KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_ASSOCIATED_DATA, input);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_ASSOCIATED_DATA, input);
// KeyStore does not reflect AAD in inputConsumed, but users of Stream rely on this
// field. We fix this discrepancy here. KeyStore.update contract is that all of AAD
@@ -425,7 +426,7 @@
}
@Override
- public OperationResult finish(byte[] additionalEntropy) {
+ public OperationResult finish(byte[] signature, byte[] additionalEntropy) {
if ((additionalEntropy != null) && (additionalEntropy.length > 0)) {
throw new ProviderException("AAD stream does not support additional entropy");
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
index fc53451..38cacd0 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
@@ -353,6 +353,7 @@
try {
output = mAdditionalAuthenticationDataStreamer.doFinal(
EmptyArray.BYTE, 0, 0,
+ null, // no signature
null // no additional entropy needed flushing AAD
);
} finally {
@@ -446,7 +447,7 @@
inputLen = input.length;
src.get(input);
}
- super.engineUpdateAAD(input, inputOffset, inputLen);
+ engineUpdateAAD(input, inputOffset, inputLen);
}
@Override
@@ -469,7 +470,10 @@
byte[] additionalEntropy =
KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
mRng, getAdditionalEntropyAmountForFinish());
- output = mMainDataStreamer.doFinal(input, inputOffset, inputLen, additionalEntropy);
+ output = mMainDataStreamer.doFinal(
+ input, inputOffset, inputLen,
+ null, // no signature involved
+ additionalEntropy);
} catch (KeyStoreException e) {
switch (e.getErrorCode()) {
case KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH:
@@ -727,6 +731,21 @@
return mMainDataStreamer.getProducedOutputSizeBytes();
}
+ static String opmodeToString(int opmode) {
+ switch (opmode) {
+ case Cipher.ENCRYPT_MODE:
+ return "ENCRYPT_MODE";
+ case Cipher.DECRYPT_MODE:
+ return "DECRYPT_MODE";
+ case Cipher.WRAP_MODE:
+ return "WRAP_MODE";
+ case Cipher.UNWRAP_MODE:
+ return "UNWRAP_MODE";
+ default:
+ return String.valueOf(opmode);
+ }
+ }
+
// The methods below need to be implemented by subclasses.
/**
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
index d19a766..10aab7e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
@@ -17,11 +17,16 @@
package android.security.keystore;
import android.annotation.NonNull;
+import android.os.IBinder;
import android.security.KeyStore;
+import android.security.KeyStoreException;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
+import libcore.util.EmptyArray;
+
+import java.io.ByteArrayOutputStream;
import java.security.InvalidKeyException;
import java.security.SignatureSpi;
@@ -36,6 +41,71 @@
public NONE() {
super(KeymasterDefs.KM_DIGEST_NONE);
}
+
+ @Override
+ protected KeyStoreCryptoOperationStreamer createMainDataStreamer(KeyStore keyStore,
+ IBinder operationToken) {
+ return new TruncateToFieldSizeMessageStreamer(
+ super.createMainDataStreamer(keyStore, operationToken),
+ getGroupSizeBits());
+ }
+
+ /**
+ * Streamer which buffers all input, then truncates it to field size, and then sends it into
+ * KeyStore via the provided delegate streamer.
+ */
+ private static class TruncateToFieldSizeMessageStreamer
+ implements KeyStoreCryptoOperationStreamer {
+
+ private final KeyStoreCryptoOperationStreamer mDelegate;
+ private final int mGroupSizeBits;
+ private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream();
+ private long mConsumedInputSizeBytes;
+
+ private TruncateToFieldSizeMessageStreamer(
+ KeyStoreCryptoOperationStreamer delegate,
+ int groupSizeBits) {
+ mDelegate = delegate;
+ mGroupSizeBits = groupSizeBits;
+ }
+
+ @Override
+ public byte[] update(byte[] input, int inputOffset, int inputLength)
+ throws KeyStoreException {
+ if (inputLength > 0) {
+ mInputBuffer.write(input, inputOffset, inputLength);
+ mConsumedInputSizeBytes += inputLength;
+ }
+ return EmptyArray.BYTE;
+ }
+
+ @Override
+ public byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] signature,
+ byte[] additionalEntropy) throws KeyStoreException {
+ if (inputLength > 0) {
+ mConsumedInputSizeBytes += inputLength;
+ mInputBuffer.write(input, inputOffset, inputLength);
+ }
+
+ byte[] bufferedInput = mInputBuffer.toByteArray();
+ mInputBuffer.reset();
+ // Truncate input at field size (bytes)
+ return mDelegate.doFinal(bufferedInput,
+ 0,
+ Math.min(bufferedInput.length, ((mGroupSizeBits + 7) / 8)),
+ signature, additionalEntropy);
+ }
+
+ @Override
+ public long getConsumedInputSizeBytes() {
+ return mConsumedInputSizeBytes;
+ }
+
+ @Override
+ public long getProducedOutputSizeBytes() {
+ return mDelegate.getProducedOutputSizeBytes();
+ }
+ }
}
public final static class SHA1 extends AndroidKeyStoreECDSASignatureSpi {
@@ -70,7 +140,7 @@
private final int mKeymasterDigest;
- private int mGroupSizeBytes = -1;
+ private int mGroupSizeBits = -1;
AndroidKeyStoreECDSASignatureSpi(int keymasterDigest) {
mKeymasterDigest = keymasterDigest;
@@ -89,18 +159,20 @@
if (errorCode != KeyStore.NO_ERROR) {
throw getKeyStore().getInvalidKeyException(key.getAlias(), errorCode);
}
- int keySizeBits = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
+ long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
if (keySizeBits == -1) {
throw new InvalidKeyException("Size of key not known");
+ } else if (keySizeBits > Integer.MAX_VALUE) {
+ throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
}
- mGroupSizeBytes = (keySizeBits + 7) / 8;
+ mGroupSizeBits = (int) keySizeBits;
super.initKey(key);
}
@Override
protected final void resetAll() {
- mGroupSizeBytes = -1;
+ mGroupSizeBits = -1;
super.resetAll();
}
@@ -110,14 +182,21 @@
}
@Override
- protected void addAlgorithmSpecificParametersToBegin(
+ protected final void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
}
@Override
- protected int getAdditionalEntropyAmountForSign() {
- return mGroupSizeBytes;
+ protected final int getAdditionalEntropyAmountForSign() {
+ return (mGroupSizeBits + 7) / 8;
+ }
+
+ protected final int getGroupSizeBits() {
+ if (mGroupSizeBits == -1) {
+ throw new IllegalStateException("Not initialized");
+ }
+ return mGroupSizeBits;
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
index f7c184c..d20e3af 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
@@ -159,9 +159,9 @@
}
KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
OperationResult opResult = mKeyStore.begin(
mKey.getAlias(),
@@ -234,6 +234,7 @@
try {
result = mChunkedStreamer.doFinal(
null, 0, 0,
+ null, // no signature provided -- this invocation will generate one
null // no additional entropy needed -- HMAC is deterministic
);
} catch (KeyStoreException e) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
index 20db41b..515be1d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
@@ -24,9 +24,12 @@
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
/**
* {@link KeyFactorySpi} backed by Android KeyStore.
@@ -40,32 +43,83 @@
@Override
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpecClass)
throws InvalidKeySpecException {
- if (keySpecClass == null) {
- throw new InvalidKeySpecException("keySpecClass == null");
- }
- if (!(key instanceof AndroidKeyStorePrivateKey)) {
- throw new InvalidKeySpecException("Only Android KeyStore private keys supported: " +
- ((key != null) ? key.getClass().getName() : "null"));
- }
- if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpecClass)) {
+ if (key == null) {
+ throw new InvalidKeySpecException("key == null");
+ } else if ((!(key instanceof AndroidKeyStorePrivateKey))
+ && (!(key instanceof AndroidKeyStorePublicKey))) {
throw new InvalidKeySpecException(
- "Key material export of Android KeyStore keys is not supported");
- }
- if (!KeyInfo.class.equals(keySpecClass)) {
- throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
- }
- String keyAliasInKeystore = ((AndroidKeyStoreKey) key).getAlias();
- String entryAlias;
- if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
- entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
- } else {
- throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
+ "Unsupported key type: " + key.getClass().getName()
+ + ". This KeyFactory supports only Android Keystore asymmetric keys");
}
- @SuppressWarnings("unchecked")
- T result = (T) AndroidKeyStoreSecretKeyFactorySpi.getKeyInfo(
- mKeyStore, entryAlias, keyAliasInKeystore);
- return result;
+ // key is an Android Keystore private or public key
+
+ if (keySpecClass == null) {
+ throw new InvalidKeySpecException("keySpecClass == null");
+ } else if (KeyInfo.class.equals(keySpecClass)) {
+ if (!(key instanceof AndroidKeyStorePrivateKey)) {
+ throw new InvalidKeySpecException(
+ "Unsupported key type: " + key.getClass().getName()
+ + ". KeyInfo can be obtained only for Android Keystore private keys");
+ }
+ String keyAliasInKeystore = ((AndroidKeyStorePrivateKey) key).getAlias();
+ String entryAlias;
+ if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
+ entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
+ } else {
+ throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
+ }
+ @SuppressWarnings("unchecked")
+ T result = (T) AndroidKeyStoreSecretKeyFactorySpi.getKeyInfo(
+ mKeyStore, entryAlias, keyAliasInKeystore);
+ return result;
+ } else if (X509EncodedKeySpec.class.equals(keySpecClass)) {
+ if (!(key instanceof AndroidKeyStorePublicKey)) {
+ throw new InvalidKeySpecException(
+ "Unsupported key type: " + key.getClass().getName()
+ + ". X509EncodedKeySpec can be obtained only for Android Keystore public"
+ + " keys");
+ }
+ @SuppressWarnings("unchecked")
+ T result = (T) new X509EncodedKeySpec(((AndroidKeyStorePublicKey) key).getEncoded());
+ return result;
+ } else if (PKCS8EncodedKeySpec.class.equals(keySpecClass)) {
+ if (key instanceof AndroidKeyStorePrivateKey) {
+ throw new InvalidKeySpecException(
+ "Key material export of Android Keystore private keys is not supported");
+ } else {
+ throw new InvalidKeySpecException(
+ "Cannot export key material of public key in PKCS#8 format."
+ + " Only X.509 format (X509EncodedKeySpec) supported for public keys.");
+ }
+ } else if (RSAPublicKeySpec.class.equals(keySpecClass)) {
+ if (key instanceof AndroidKeyStoreRSAPublicKey) {
+ AndroidKeyStoreRSAPublicKey rsaKey = (AndroidKeyStoreRSAPublicKey) key;
+ @SuppressWarnings("unchecked")
+ T result =
+ (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
+ return result;
+ } else {
+ throw new InvalidKeySpecException(
+ "Obtaining RSAPublicKeySpec not supported for " + key.getAlgorithm() + " "
+ + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public")
+ + " key");
+ }
+ } else if (ECPublicKeySpec.class.equals(keySpecClass)) {
+ if (key instanceof AndroidKeyStoreECPublicKey) {
+ AndroidKeyStoreECPublicKey ecKey = (AndroidKeyStoreECPublicKey) key;
+ @SuppressWarnings("unchecked")
+ T result = (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
+ return result;
+ } else {
+ throw new InvalidKeySpecException(
+ "Obtaining ECPublicKeySpec not supported for " + key.getAlgorithm() + " "
+ + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public")
+ + " key");
+ }
+ } else {
+ throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
+ }
}
@Override
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 688936c..258133d 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;
@@ -269,24 +268,20 @@
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
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..459514d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -160,7 +160,7 @@
private int[] mKeymasterSignaturePaddings;
private int[] mKeymasterDigests;
- private long mRSAPublicExponent;
+ private BigInteger mRSAPublicExponent;
protected AndroidKeyStoreKeyPairGeneratorSpi(int keymasterAlgorithm) {
mOriginalKeymasterAlgorithm = keymasterAlgorithm;
@@ -287,6 +287,22 @@
mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
mKeymasterEncryptionPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
spec.getEncryptionPaddings());
+ if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
+ && (spec.isRandomizedEncryptionRequired())) {
+ for (int keymasterPadding : mKeymasterEncryptionPaddings) {
+ if (!KeymasterUtils
+ .isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
+ keymasterPadding)) {
+ throw new InvalidAlgorithmParameterException(
+ "Randomized encryption (IND-CPA) required but may be violated"
+ + " by padding scheme: "
+ + KeyProperties.EncryptionPadding.fromKeymaster(
+ keymasterPadding)
+ + ". See " + KeyGenParameterSpec.class.getName()
+ + " documentation.");
+ }
+ }
+ }
mKeymasterSignaturePaddings = KeyProperties.SignaturePadding.allToKeymaster(
spec.getSignaturePaddings());
if (spec.isDigestsSpecified()) {
@@ -320,7 +336,7 @@
mKeymasterDigests = null;
mKeySizeBits = 0;
mSpec = null;
- mRSAPublicExponent = -1;
+ mRSAPublicExponent = null;
mEncryptionAtRestRequired = false;
mRng = null;
mKeyStore = null;
@@ -353,12 +369,12 @@
throw new InvalidAlgorithmParameterException(
"RSA public exponent must be positive: " + publicExponent);
}
- if (publicExponent.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
+ if (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0) {
throw new InvalidAlgorithmParameterException(
"Unsupported RSA public exponent: " + publicExponent
- + ". Only exponents <= " + Long.MAX_VALUE + " supported");
+ + ". Maximum supported value: " + KeymasterArguments.UINT64_MAX_VALUE);
}
- mRSAPublicExponent = publicExponent.longValue();
+ mRSAPublicExponent = publicExponent;
break;
}
case KeymasterDefs.KM_ALGORITHM_EC:
@@ -404,26 +420,22 @@
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterEncryptionPaddings);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterEncryptionPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
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 =
@@ -497,7 +509,8 @@
private void addAlgorithmSpecificParameters(KeymasterArguments keymasterArgs) {
switch (mKeymasterAlgorithm) {
case KeymasterDefs.KM_ALGORITHM_RSA:
- keymasterArgs.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, mRSAPublicExponent);
+ keymasterArgs.addUnsignedLong(
+ KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, mRSAPublicExponent);
break;
case KeymasterDefs.KM_ALGORITHM_EC:
break;
@@ -515,15 +528,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 +645,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 +747,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/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 967319a..ba39ba7 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -226,8 +226,8 @@
}
final byte[] x509EncodedPublicKey = exportResult.exportData;
- int keymasterAlgorithm = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_ALGORITHM, -1);
- if (keymasterAlgorithm == -1) {
+ Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
+ if (keymasterAlgorithm == null) {
throw new UnrecoverableKeyException("Key algorithm unknown");
}
@@ -277,13 +277,12 @@
.initCause(KeyStore.getKeyStoreException(errorCode));
}
- int keymasterAlgorithm = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_ALGORITHM, -1);
- if (keymasterAlgorithm == -1) {
+ Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
+ if (keymasterAlgorithm == null) {
throw new UnrecoverableKeyException("Key algorithm unknown");
}
- List<Integer> keymasterDigests =
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST);
+ List<Integer> keymasterDigests = keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST);
int keymasterDigest;
if (keymasterDigests.isEmpty()) {
keymasterDigest = -1;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
index 38e216d..94ed8b4 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
@@ -60,9 +60,10 @@
}
@Override
- protected boolean isEncryptingUsingPrivateKeyPermitted() {
- // RSA encryption with no padding using private key is is a way to implement raw RSA
- // signatures. We have to support this.
+ protected boolean adjustConfigForEncryptingWithPrivateKey() {
+ // RSA encryption with no padding using private key is a way to implement raw RSA
+ // signatures which JCA does not expose via Signature. We thus have to support this.
+ setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
return true;
}
@@ -150,8 +151,7 @@
@Override
public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
- byte[] additionalEntropy)
- throws KeyStoreException {
+ byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
if (inputLength > 0) {
mConsumedInputSizeBytes += inputLength;
mInputBuffer.write(input, inputOffset, inputLength);
@@ -174,7 +174,8 @@
"Message size (" + bufferedInput.length + " bytes) must be smaller than"
+ " modulus (" + mModulusSizeBytes + " bytes)");
}
- return mDelegate.doFinal(paddedInput, 0, paddedInput.length, additionalEntropy);
+ return mDelegate.doFinal(paddedInput, 0, paddedInput.length, signature,
+ additionalEntropy);
}
@Override
@@ -198,6 +199,15 @@
}
@Override
+ protected boolean adjustConfigForEncryptingWithPrivateKey() {
+ // RSA encryption with PCKS#1 padding using private key is a way to implement RSA
+ // signatures with PKCS#1 padding. We have to support this for legacy reasons.
+ setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
+ setKeymasterPaddingOverride(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
+ return true;
+ }
+
+ @Override
protected void initAlgorithmSpecificParameters() throws InvalidKeyException {}
@Override
@@ -374,7 +384,7 @@
protected final void addAlgorithmSpecificParametersToBegin(
KeymasterArguments keymasterArgs) {
super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
}
@Override
@@ -425,6 +435,7 @@
}
private final int mKeymasterPadding;
+ private int mKeymasterPaddingOverride;
private int mModulusSizeBytes = -1;
@@ -458,20 +469,15 @@
// Permitted
break;
case Cipher.ENCRYPT_MODE:
- if (!isEncryptingUsingPrivateKeyPermitted()) {
+ case Cipher.WRAP_MODE:
+ if (!adjustConfigForEncryptingWithPrivateKey()) {
throw new InvalidKeyException(
- "RSA private keys cannot be used with Cipher.ENCRYPT_MODE"
+ "RSA private keys cannot be used with " + opmodeToString(opmode)
+ + " and padding "
+ + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
+ ". Only RSA public keys supported for this mode");
}
- // JCA doesn't provide a way to generate raw RSA signatures (with arbitrary
- // padding). Thus, encrypting with private key is used instead.
- setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
break;
- case Cipher.WRAP_MODE:
- throw new InvalidKeyException(
- "RSA private keys cannot be used with Cipher.WRAP_MODE"
- + ". Only RSA public keys supported for this mode");
- // break;
default:
throw new InvalidKeyException(
"RSA private keys cannot be used with opmode: " + opmode);
@@ -485,12 +491,15 @@
break;
case Cipher.DECRYPT_MODE:
case Cipher.UNWRAP_MODE:
- throw new InvalidKeyException("RSA public keys cannot be used with opmode: "
- + opmode + ". Only RSA private keys supported for this opmode.");
+ throw new InvalidKeyException(
+ "RSA public keys cannot be used with " + opmodeToString(opmode)
+ + " and padding "
+ + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
+ + ". Only RSA private keys supported for this opmode.");
// break;
default:
throw new InvalidKeyException(
- "RSA public keys cannot be used with opmode: " + opmode);
+ "RSA public keys cannot be used with " + opmodeToString(opmode));
}
}
@@ -500,22 +509,33 @@
if (errorCode != KeyStore.NO_ERROR) {
throw getKeyStore().getInvalidKeyException(keystoreKey.getAlias(), errorCode);
}
- int keySizeBits = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
+ long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
if (keySizeBits == -1) {
throw new InvalidKeyException("Size of key not known");
+ } else if (keySizeBits > Integer.MAX_VALUE) {
+ throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
}
- mModulusSizeBytes = (keySizeBits + 7) / 8;
+ mModulusSizeBytes = (int) ((keySizeBits + 7) / 8);
setKey(keystoreKey);
}
- protected boolean isEncryptingUsingPrivateKeyPermitted() {
+ /**
+ * Adjusts the configuration of this cipher for encrypting using the private key.
+ *
+ * <p>The default implementation does nothing and refuses to adjust the configuration.
+ *
+ * @return {@code true} if the configuration has been adjusted, {@code false} if encrypting
+ * using private key is not permitted for this cipher.
+ */
+ protected boolean adjustConfigForEncryptingWithPrivateKey() {
return false;
}
@Override
protected final void resetAll() {
mModulusSizeBytes = -1;
+ mKeymasterPaddingOverride = -1;
super.resetAll();
}
@@ -527,14 +547,18 @@
@Override
protected void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ int keymasterPadding = getKeymasterPaddingOverride();
+ if (keymasterPadding == -1) {
+ keymasterPadding = mKeymasterPadding;
+ }
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
int purposeOverride = getKeymasterPurposeOverride();
if ((purposeOverride != -1)
&& ((purposeOverride == KeymasterDefs.KM_PURPOSE_SIGN)
|| (purposeOverride == KeymasterDefs.KM_PURPOSE_VERIFY))) {
// Keymaster sign/verify requires digest to be specified. For raw sign/verify it's NONE.
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
}
}
@@ -566,4 +590,15 @@
}
return mModulusSizeBytes;
}
+
+ /**
+ * Overrides the default padding of the crypto operation.
+ */
+ protected final void setKeymasterPaddingOverride(int keymasterPadding) {
+ mKeymasterPaddingOverride = keymasterPadding;
+ }
+
+ protected final int getKeymasterPaddingOverride() {
+ return mKeymasterPaddingOverride;
+ }
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
index 954b71a..ecfc97e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
@@ -157,8 +157,8 @@
@Override
protected final void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 8b00821..9a2f908 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -93,26 +93,29 @@
if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = true;
origin = KeyProperties.Origin.fromKeymaster(
- keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
+ keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = false;
origin = KeyProperties.Origin.fromKeymaster(
- keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
+ keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else {
throw new ProviderException("Key origin not available");
}
- Integer keySizeInteger = keyCharacteristics.getInteger(KeymasterDefs.KM_TAG_KEY_SIZE);
- if (keySizeInteger == null) {
+ long keySizeUnsigned =
+ keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
+ if (keySizeUnsigned == -1) {
throw new ProviderException("Key size not available");
+ } else if (keySizeUnsigned > Integer.MAX_VALUE) {
+ throw new ProviderException("Key too large: " + keySizeUnsigned + " bits");
}
- keySize = keySizeInteger;
+ keySize = (int) keySizeUnsigned;
purposes = KeyProperties.Purpose.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PURPOSE));
+ keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PURPOSE));
List<String> encryptionPaddingsList = new ArrayList<String>();
List<String> signaturePaddingsList = new ArrayList<String>();
// Keymaster stores both types of paddings in the same array -- we split it into two.
- for (int keymasterPadding : keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PADDING)) {
+ for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
try {
@KeyProperties.EncryptionPaddingEnum String jcaPadding =
KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
@@ -135,37 +138,30 @@
signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
digests = KeyProperties.Digest.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
+ keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
blockModes = KeyProperties.BlockMode.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
+ keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
keymasterSwEnforcedUserAuthenticators =
- keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
keymasterHwEnforcedUserAuthenticators =
- keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
} catch (IllegalArgumentException e) {
throw new ProviderException("Unsupported key characteristic", e);
}
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 =
- keyCharacteristics.getInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
+ long userAuthenticationValidityDurationSeconds =
+ keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
+ if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) {
+ throw new ProviderException("User authentication timeout validity too long: "
+ + userAuthenticationValidityDurationSeconds + " seconds");
+ }
boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired)
&& (keymasterHwEnforcedUserAuthenticators != 0)
&& (keymasterSwEnforcedUserAuthenticators == 0);
@@ -183,7 +179,7 @@
digests,
blockModes,
userAuthenticationRequired,
- userAuthenticationValidityDurationSeconds,
+ (int) userAuthenticationValidityDurationSeconds,
userAuthenticationRequirementEnforcedBySecureHardware);
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java b/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java
index 5cdcc41..76240dd 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSignatureSpiBase.java
@@ -58,7 +58,7 @@
*/
private IBinder mOperationToken;
private long mOperationHandle;
- private KeyStoreCryptoOperationChunkedStreamer mMessageStreamer;
+ private KeyStoreCryptoOperationStreamer mMessageStreamer;
/**
* Encountered exception which could not be immediately thrown because it was encountered inside
@@ -229,9 +229,20 @@
throw new ProviderException("Keystore returned invalid operation handle");
}
- mMessageStreamer = new KeyStoreCryptoOperationChunkedStreamer(
+ mMessageStreamer = createMainDataStreamer(mKeyStore, opResult.token);
+ }
+
+ /**
+ * Creates a streamer which sends the message to be signed/verified into the provided KeyStore
+ *
+ * <p>This implementation returns a working streamer.
+ */
+ @NonNull
+ protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
+ KeyStore keyStore, IBinder operationToken) {
+ return new KeyStoreCryptoOperationChunkedStreamer(
new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
- mKeyStore, opResult.token));
+ keyStore, operationToken));
}
@Override
@@ -314,7 +325,10 @@
byte[] additionalEntropy =
KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
appRandom, getAdditionalEntropyAmountForSign());
- signature = mMessageStreamer.doFinal(EmptyArray.BYTE, 0, 0, additionalEntropy);
+ signature = mMessageStreamer.doFinal(
+ EmptyArray.BYTE, 0, 0,
+ null, // no signature provided -- it'll be generated by this invocation
+ additionalEntropy);
} catch (InvalidKeyException | KeyStoreException e) {
throw new SignatureException(e);
}
@@ -329,31 +343,37 @@
throw new SignatureException(mCachedException);
}
- boolean result;
try {
ensureKeystoreOperationInitialized();
- mMessageStreamer.flush();
- OperationResult opResult = mKeyStore.finish(mOperationToken, null, signature);
- if (opResult == null) {
- throw new KeyStoreConnectException();
- }
- switch (opResult.resultCode) {
- case KeyStore.NO_ERROR:
- result = true;
- break;
- case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
- result = false;
- break;
- default:
- throw new SignatureException(
- KeyStore.getKeyStoreException(opResult.resultCode));
- }
- } catch (InvalidKeyException | KeyStoreException e) {
+ } catch (InvalidKeyException e) {
throw new SignatureException(e);
}
+ boolean verified;
+ try {
+ byte[] output = mMessageStreamer.doFinal(
+ EmptyArray.BYTE, 0, 0,
+ signature,
+ null // no additional entropy needed -- verification is deterministic
+ );
+ if (output.length != 0) {
+ throw new ProviderException(
+ "Signature verification unexpected produced output: " + output.length
+ + " bytes");
+ }
+ verified = true;
+ } catch (KeyStoreException e) {
+ switch (e.getErrorCode()) {
+ case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
+ verified = false;
+ break;
+ default:
+ throw new SignatureException(e);
+ }
+ }
+
resetWhilePreservingInitState();
- return result;
+ return verified;
}
@Override
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 5fb589e..dc8f1e3 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -140,21 +140,64 @@
throw new NullPointerException("alias == null");
}
- byte[] certificate = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
- if (certificate != null) {
- return wrapIntoKeyStoreCertificate(
- Credentials.USER_PRIVATE_KEY + alias, toCertificate(certificate));
+ byte[] encodedCert = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
+ if (encodedCert != null) {
+ return getCertificateForPrivateKeyEntry(alias, encodedCert);
}
- certificate = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
- if (certificate != null) {
- return wrapIntoKeyStoreCertificate(
- Credentials.USER_PRIVATE_KEY + alias, toCertificate(certificate));
+ encodedCert = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
+ if (encodedCert != null) {
+ return getCertificateForTrustedCertificateEntry(encodedCert);
}
+ // This entry/alias does not contain a certificate.
return null;
}
+ private Certificate getCertificateForTrustedCertificateEntry(byte[] encodedCert) {
+ // For this certificate there shouldn't be a private key in this KeyStore entry. Thus,
+ // there's no need to wrap this certificate as opposed to the certificate associated with
+ // a private key entry.
+ return toCertificate(encodedCert);
+ }
+
+ private Certificate getCertificateForPrivateKeyEntry(String alias, byte[] encodedCert) {
+ // All crypto algorithms offered by Android Keystore for its private keys must also
+ // be offered for the corresponding public keys stored in the Android Keystore. The
+ // complication is that the underlying keystore service operates only on full key pairs,
+ // rather than just public keys or private keys. As a result, Android Keystore-backed
+ // crypto can only be offered for public keys for which keystore contains the
+ // corresponding private key. This is not the case for certificate-only entries (e.g.,
+ // trusted certificates).
+ //
+ // getCertificate().getPublicKey() is the only way to obtain the public key
+ // corresponding to the private key stored in the KeyStore. Thus, we need to make sure
+ // that the returned public key points to the underlying key pair / private key
+ // when available.
+
+ X509Certificate cert = toCertificate(encodedCert);
+ if (cert == null) {
+ // Failed to parse the certificate.
+ return null;
+ }
+
+ String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
+ if (mKeyStore.contains(privateKeyAlias)) {
+ // As expected, keystore contains the private key corresponding to this public key. Wrap
+ // the certificate so that its getPublicKey method returns an Android Keystore
+ // PublicKey. This key will delegate crypto operations involving this public key to
+ // Android Keystore when higher-priority providers do not offer these crypto
+ // operations for this key.
+ return wrapIntoKeyStoreCertificate(privateKeyAlias, cert);
+ } else {
+ // This KeyStore entry/alias is supposed to contain the private key corresponding to
+ // the public key in this certificate, but it does not for some reason. It's probably a
+ // bug. Let other providers handle crypto operations involving the public key returned
+ // by this certificate's getPublicKey.
+ return cert;
+ }
+ }
+
/**
* Wraps the provided cerificate into {@link KeyStoreX509Certificate} so that the public key
* returned by the certificate contains information about the alias of the private key in
@@ -398,18 +441,18 @@
importArgs = new KeymasterArguments();
try {
- importArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM,
+ importArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM,
KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
key.getAlgorithm()));
@KeyProperties.PurposeEnum int purposes = spec.getPurposes();
- importArgs.addInts(KeymasterDefs.KM_TAG_PURPOSE,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PURPOSE,
KeyProperties.Purpose.allToKeymaster(purposes));
if (spec.isDigestsSpecified()) {
- importArgs.addInts(KeymasterDefs.KM_TAG_DIGEST,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_DIGEST,
KeyProperties.Digest.allToKeymaster(spec.getDigests()));
}
- importArgs.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE,
KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()));
int[] keymasterEncryptionPaddings =
KeyProperties.EncryptionPadding.allToKeymaster(
@@ -429,23 +472,18 @@
}
}
}
- importArgs.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
- importArgs.addInts(KeymasterDefs.KM_TAG_PADDING,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
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);
}
@@ -572,7 +610,7 @@
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
int[] keymasterDigests;
if (params.isDigestsSpecified()) {
@@ -611,7 +649,7 @@
keymasterDigests = EmptyArray.INT;
}
}
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
if (keymasterDigests.length == 0) {
throw new KeyStoreException("At least one digest algorithm must be specified"
@@ -635,26 +673,22 @@
}
}
}
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
if (params.getSignaturePaddings().length > 0) {
throw new KeyStoreException("Signature paddings not supported for symmetric keys");
}
int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
params.getEncryptionPaddings());
- args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
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/AndroidKeyStoreUnauthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
index 6c53c6a..486519c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
@@ -240,11 +240,11 @@
+ " practices.");
}
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
if ((mIvRequired) && (mIv != null)) {
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_NONCE, mIv);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
}
}
@@ -254,7 +254,7 @@
mIvHasBeenUsed = true;
// NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBlob(KeymasterDefs.KM_TAG_NONCE, null);
+ byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
if ((returnedIv != null) && (returnedIv.length == 0)) {
returnedIv = null;
}
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/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index 894d52a..ea0f4b9 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -35,8 +35,8 @@
* amount of data in one go because the operations are marshalled via Binder. Secondly, the update
* operation may consume less data than provided, in which case the caller has to buffer the
* remainder for next time. The helper exposes {@link #update(byte[], int, int) update} and
- * {@link #doFinal(byte[], int, int, byte[]) doFinal} operations which can be used to conveniently
- * implement various JCA crypto primitives.
+ * {@link #doFinal(byte[], int, int, byte[], byte[]) doFinal} operations which can be used to
+ * conveniently implement various JCA crypto primitives.
*
* <p>Bidirectional chunked streaming of data via a KeyStore crypto operation is abstracted away as
* a {@link Stream} to avoid having this class deal with operation tokens and occasional additional
@@ -60,7 +60,7 @@
* Returns the result of the KeyStore {@code finish} operation or null if keystore couldn't
* be reached.
*/
- OperationResult finish(byte[] additionalEntropy);
+ OperationResult finish(byte[] siganture, byte[] additionalEntropy);
}
// Binder buffer is about 1MB, but it's shared between all active transactions of the process.
@@ -201,8 +201,8 @@
}
@Override
- public byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] additionalEntropy)
- throws KeyStoreException {
+ public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
+ byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
if (inputLength == 0) {
// No input provided -- simplify the rest of the code
input = EmptyArray.BYTE;
@@ -213,7 +213,7 @@
byte[] output = update(input, inputOffset, inputLength);
output = ArrayUtils.concat(output, flush());
- OperationResult opResult = mKeyStoreStream.finish(additionalEntropy);
+ OperationResult opResult = mKeyStoreStream.finish(signature, additionalEntropy);
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
@@ -286,8 +286,8 @@
}
@Override
- public OperationResult finish(byte[] additionalEntropy) {
- return mKeyStore.finish(mOperationToken, null, null, additionalEntropy);
+ public OperationResult finish(byte[] signature, byte[] additionalEntropy) {
+ return mKeyStore.finish(mOperationToken, null, signature, additionalEntropy);
}
}
}
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java
index 897bd71..062c2d4 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java
@@ -28,15 +28,15 @@
* amount of data in one go because the operations are marshalled via Binder. Secondly, the update
* operation may consume less data than provided, in which case the caller has to buffer the
* remainder for next time. The helper exposes {@link #update(byte[], int, int) update} and
- * {@link #doFinal(byte[], int, int, byte[]) doFinal} operations which can be used to conveniently
- * implement various JCA crypto primitives.
+ * {@link #doFinal(byte[], int, int, byte[], byte[]) doFinal} operations which can be used to
+ * conveniently implement various JCA crypto primitives.
*
* @hide
*/
interface KeyStoreCryptoOperationStreamer {
byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException;
- byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] additionalEntropy)
- throws KeyStoreException;
+ byte[] doFinal(byte[] input, int inputOffset, int inputLength, byte[] signature,
+ byte[] additionalEntropy) throws KeyStoreException;
long getConsumedInputSizeBytes();
long getProducedOutputSizeBytes();
}
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 4b37d90..3cd3f2a 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -74,7 +74,7 @@
return true;
default:
throw new IllegalArgumentException(
- "Unsupported encryption padding scheme: " + keymasterPadding);
+ "Unsupported asymmetric encryption padding scheme: " + keymasterPadding);
}
}
@@ -110,8 +110,9 @@
"At least one fingerprint must be enrolled to create keys requiring user"
+ " authentication for every use");
}
- args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, fingerprintOnlySid);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
+ KeymasterArguments.toUint64(fingerprintOnlySid));
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
} else {
// The key is authorized for use for the specified amount of time after the user has
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -120,10 +121,11 @@
throw new IllegalStateException("Secure lock screen must be enabled"
+ " to create keys requiring user authentication");
}
- args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, rootSid);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
+ KeymasterArguments.toUint64(rootSid));
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
- args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
userAuthenticationValidityDurationSeconds);
}
}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 0b60c62..319cf32 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -702,14 +702,13 @@
private KeyCharacteristics generateRsaKey(String name) throws Exception {
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
@@ -726,14 +725,13 @@
byte[] entropy = new byte[] {1,2,3,4,5};
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, entropy, 0, outCharacteristics);
@@ -759,16 +757,15 @@
String name = "test";
byte[] id = new byte[] {0x01, 0x02, 0x03};
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ args.addBytes(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
@@ -795,12 +792,12 @@
public void testAesGcmEncryptSuccess() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
@@ -808,10 +805,10 @@
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
true, args, null);
IBinder token = result.token;
@@ -832,12 +829,12 @@
private int importAesKey(String name, byte[] key, int size, int mode) {
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
return mKeyStore.importKey(name, args, KeymasterDefs.KM_KEY_FORMAT_RAW, key, 0,
new KeyCharacteristics());
@@ -877,9 +874,9 @@
hexToBytes("b6ed21b99ca6f4f9f153e7b1beafed1d"),
hexToBytes("23304b7a39f9f3ff067d8d8f9e24ecc7")};
KeymasterArguments beginArgs = new KeymasterArguments();
- beginArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- beginArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
- beginArgs.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
for (int i = 0; i < testVectors.length; i++) {
byte[] cipherText = doOperation(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, testVectors[i],
beginArgs);
@@ -897,12 +894,12 @@
public void testOperationPruning() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
@@ -910,9 +907,9 @@
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
true, args, null);
assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
@@ -930,13 +927,13 @@
public void testAuthNeeded() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 6f927b4..a6f6d8c 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -126,10 +126,18 @@
return true;
}
-bool ZipFileRO::startIteration(void** cookie)
+bool ZipFileRO::startIteration(void** cookie) {
+ return startIteration(cookie, NULL, NULL);
+}
+
+bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix)
{
_ZipEntryRO* ze = new _ZipEntryRO;
- int32_t error = StartIteration(mHandle, &(ze->cookie), NULL /* prefix */);
+ ZipEntryName pe(prefix ? prefix : "");
+ ZipEntryName se(suffix ? suffix : "");
+ int32_t error = StartIteration(mHandle, &(ze->cookie),
+ prefix ? &pe : NULL,
+ suffix ? &se : NULL);
if (error) {
ALOGW("Could not start iteration over %s: %s", mFileName, ErrorCodeString(error));
delete ze;
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index aa24673..562bb80 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -47,6 +47,10 @@
* It is useful for testing and clients (e.g. Picture/Movie) that expect to
* draw their contents into an SkCanvas.
*
+ * The SkCanvas returned is *only* valid until another Canvas call is made
+ * that would change state (e.g. matrix or clip). Clients of asSkCanvas()
+ * are responsible for *not* persisting this pointer.
+ *
* Further, the returned SkCanvas should NOT be unref'd and is valid until
* this canvas is destroyed or a new bitmap is set.
*/
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 843c412..b08187b 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -99,6 +99,14 @@
if (!mSkiaCanvasProxy) {
mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
}
+
+ // SkCanvas instances default to identity transform, but should inherit
+ // the state of this Canvas; if this code was in the SkiaCanvasProxy
+ // constructor, we couldn't cache mSkiaCanvasProxy.
+ SkMatrix parentTransform;
+ getMatrix(&parentTransform);
+ mSkiaCanvasProxy.get()->setMatrix(parentTransform);
+
return mSkiaCanvasProxy.get();
}
@@ -135,6 +143,8 @@
}
void DisplayListCanvas::translate(float dx, float dy) {
+ if (dx == 0.0f && dy == 0.0f) return;
+
mHasDeferredTranslate = true;
mTranslateX += dx;
mTranslateY += dy;
@@ -143,11 +153,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/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 433e178..3d48fa69 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1097,7 +1097,7 @@
}
void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
- if (bounds.intersect(mState.currentClipRect())) {
+ if (CC_LIKELY(!bounds.isEmpty() && bounds.intersect(mState.currentClipRect()))) {
bounds.snapToPixelBoundaries();
android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
if (!dirty.isEmpty()) {
@@ -1146,7 +1146,7 @@
.setTransform(*currentSnapshot(), transformFlags)
.setModelViewOffsetRect(0, 0, Rect(currentSnapshot()->getClipRect()))
.build();
- renderGlop(glop, false);
+ renderGlop(glop, GlopRenderType::LayerClear);
if (scissorChanged) mRenderState.scissor().setEnabled(true);
} else {
@@ -1454,10 +1454,15 @@
#endif
}
-void OpenGLRenderer::renderGlop(const Glop& glop, bool clearLayer) {
+void OpenGLRenderer::renderGlop(const Glop& glop, GlopRenderType type) {
// TODO: It would be best if we could do this before quickRejectSetupScissor()
// changes the scissor test state
- if (clearLayer) clearLayerRegions();
+ if (type != GlopRenderType::LayerClear) {
+ // Regular draws need to clear the dirty area on the layer before they start drawing on top
+ // of it. If this draw *is* a layer clear, it skips the clear step (since it would
+ // infinitely recurse)
+ clearLayerRegions();
+ }
if (mState.getDirtyClip()) {
if (mRenderState.scissor().isEnabled()) {
@@ -1467,7 +1472,7 @@
setStencilFromClip();
}
mRenderState.render(glop);
- if (!mRenderState.stencil().isWriteEnabled()) {
+ if (type == GlopRenderType::Standard && !mRenderState.stencil().isWriteEnabled()) {
// TODO: specify more clearly when a draw should dirty the layer.
// is writing to the stencil the only time we should ignore this?
dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom);
@@ -1540,7 +1545,7 @@
.setTransform(*currentSnapshot(), transformFlags)
.setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight()))
.build();
- renderGlop(glop);
+ renderGlop(glop, GlopRenderType::Multi);
}
void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
@@ -1738,7 +1743,7 @@
.setTransform(*currentSnapshot(), transformFlags)
.setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0))
.build();
- renderGlop(glop);
+ renderGlop(glop, GlopRenderType::Multi);
}
void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 5850dc6..800a9f9 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -535,7 +535,13 @@
RenderState& mRenderState;
private:
- void renderGlop(const Glop& glop, bool clearLayer = true);
+ enum class GlopRenderType {
+ Standard,
+ Multi,
+ LayerClear
+ };
+
+ void renderGlop(const Glop& glop, GlopRenderType type = GlopRenderType::Standard);
/**
* Discards the content of the framebuffer if supported by the driver.
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 5e9b213..c98932c 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -19,6 +19,7 @@
#include <SkPath.h>
#include "Rect.h"
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
@@ -85,6 +86,11 @@
return mShouldClip && (mType == kOutlineType_RoundRect);
}
+ bool willRoundRectClip() const {
+ // only round rect outlines can be used for clipping
+ return willClip() && MathUtils::isPositive(mRadius);
+ }
+
bool getAsRoundRect(Rect* outRect, float* outRadius) const {
if (mType == kOutlineType_RoundRect) {
outRect->set(mBounds);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 81cf2df..11abd70 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -169,7 +169,7 @@
bool functorsNeedLayer = ancestorDictatesFunctorsNeedLayer
// Round rect clipping forces layer for functors
- || CC_UNLIKELY(getOutline().willClip())
+ || CC_UNLIKELY(getOutline().willRoundRectClip())
|| CC_UNLIKELY(getRevealClip().willClip())
// Complex matrices forces layer, due to stencil clipping
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 024ff10..09d1258 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
+#include <utils/MathUtils.h>
#include "AmbientShadow.h"
#include "Properties.h"
@@ -172,6 +173,8 @@
// acos( ) --- [0, M_PI]
// floor(...) --- [0, EXTRA_VERTEX_PER_PI]
float dotProduct = vector1.dot(vector2);
+ // make sure that dotProduct value is in acsof input range [-1, 1]
+ dotProduct = MathUtils::clamp(dotProduct, -1.0f, 1.0f);
// TODO: Use look up table for the dotProduct to extraVerticesNumber
// computation, if needed.
float angle = acosf(dotProduct);
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/font/Font.cpp b/libs/hwui/font/Font.cpp
index b07a3c8..5de64a4 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -228,15 +228,15 @@
for (uint32_t cacheY = startY, bitmapY = dstY * bitmapWidth; cacheY < endY;
cacheY += srcStride, bitmapY += bitmapWidth) {
- if (formatSize == 1) {
- memcpy(&bitmap[bitmapY + dstX], &cacheBuffer[cacheY + glyph->mStartX], glyph->mBitmapWidth);
- } else {
- for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) {
- bitmap[bitmapY + dstX + i] = cacheBuffer[cacheY + (glyph->mStartX + i)*formatSize + alpha_channel_offset];
- }
+ for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) {
+ uint8_t* dst = &(bitmap[bitmapY + dstX + i]);
+ const uint8_t& src = cacheBuffer[
+ cacheY + (glyph->mStartX + i)*formatSize + alpha_channel_offset];
+ // Add alpha values to a max of 255, full opacity. This is done to handle
+ // fonts/strings where glyphs overlap.
+ *dst = std::min(*dst + src, 255);
}
}
-
}
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
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/AudioManager.java b/media/java/android/media/AudioManager.java
index a806440..2c28d8e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -204,6 +204,17 @@
public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
/**
+ * @hide
+ * The stream type alias for the volume changed intent.
+ * For instance the intent may indicate a change of the {@link #STREAM_NOTIFICATION} stream
+ * type (as indicated by the {@link #EXTRA_VOLUME_STREAM_TYPE} extra), but this is also
+ * reflected by a change of the volume of its alias, {@link #STREAM_RING} on some devices,
+ * {@link #STREAM_MUSIC} on others (e.g. a television).
+ */
+ public static final String EXTRA_VOLUME_STREAM_TYPE_ALIAS =
+ "android.media.EXTRA_VOLUME_STREAM_TYPE_ALIAS";
+
+ /**
* @hide The volume associated with the stream for the volume changed intent.
*/
public static final String EXTRA_VOLUME_STREAM_VALUE =
@@ -619,10 +630,6 @@
com.android.internal.R.bool.config_useVolumeKeySounds);
mUseFixedVolume = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
- sAudioPortEventHandler.init();
-
- mPortListener = new OnAmPortUpdateListener();
- registerAudioPortUpdateListener(mPortListener);
}
private Context getContext() {
@@ -3554,6 +3561,7 @@
* @hide
*/
public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) {
+ sAudioPortEventHandler.init();
sAudioPortEventHandler.registerListener(l);
}
@@ -3586,6 +3594,7 @@
static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches,
ArrayList<AudioPort> previousPorts) {
+ sAudioPortEventHandler.init();
synchronized (sAudioPortGeneration) {
if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
@@ -3849,6 +3858,12 @@
android.os.Handler handler) {
if (callback != null && !mDeviceCallbacks.containsKey(callback)) {
synchronized (mDeviceCallbacks) {
+ if (mDeviceCallbacks.size() == 0) {
+ if (mPortListener == null) {
+ mPortListener = new OnAmPortUpdateListener();
+ }
+ registerAudioPortUpdateListener(mPortListener);
+ }
NativeEventHandlerDelegate delegate =
new NativeEventHandlerDelegate(callback, handler);
mDeviceCallbacks.put(callback, delegate);
@@ -3867,6 +3882,9 @@
synchronized (mDeviceCallbacks) {
if (mDeviceCallbacks.containsKey(callback)) {
mDeviceCallbacks.remove(callback);
+ if (mDeviceCallbacks.size() == 0) {
+ unregisterAudioPortUpdateListener(mPortListener);
+ }
}
}
}
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/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 6c26220..28d0713 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -705,6 +705,9 @@
int maxInstances = Utils.parseIntSafely(
map.get("max-supported-instances"), mMaxSupportedInstances);
+ // TODO: replace all max-supported-instances with max-concurrent-instances.
+ maxInstances = Utils.parseIntSafely(
+ map.get("max-concurrent-instances"), maxInstances);
mMaxSupportedInstances =
Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 9acfee2..ab61e2b 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -89,10 +89,23 @@
* encrypted content, the samples returned from the extractor remain encrypted, they
* are only decrypted when the samples are delivered to the decoder.
* <p>
- * MediaDrm methods throw {@link java.lang.IllegalStateException}
- * when a method is called on a MediaDrm object that is in an invalid or inoperable
- * state. This is typically due to incorrect application API usage, but may also
- * be due to an unrecoverable failure in the DRM plugin or security hardware.
+ * MediaDrm methods throw {@link android.media.MediaDrm.MediaDrmStateException}
+ * when a method is called on a MediaDrm object that has had an unrecoverable failure
+ * in the DRM plugin or security hardware.
+ * {@link android.media.MediaDrm.MediaDrmStateException} extends
+ * {@link java.lang.IllegalStateException} with the addition of a developer-readable
+ * diagnostic information string associated with the exception.
+ * <p>
+ * In the event of a mediaserver process crash or restart while a MediaDrm object
+ * is active, MediaDrm methods may throw {@link android.media.MediaDrmResetException}.
+ * To recover, the app must release the MediaDrm object, then create and initialize
+ * a new one.
+ * <p>
+ * As {@link android.media.MediaDrmResetException} and
+ * {@link android.media.MediaDrm.MediaDrmStateException} both extend
+ * {@link java.lang.IllegalStateException}, they should be in an earlier catch()
+ * block than {@link java.lang.IllegalStateException} if handled separately.
+ * <p>
* <a name="Callbacks"></a>
* <h3>Callbacks</h3>
* <p>Applications should register for informational events in order
diff --git a/media/java/android/media/MediaDrmResetException.java b/media/java/android/media/MediaDrmResetException.java
new file mode 100644
index 0000000..3b2da1e
--- /dev/null
+++ b/media/java/android/media/MediaDrmResetException.java
@@ -0,0 +1,28 @@
+/*
+ * 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 android.media;
+
+/**
+ * This exception is thrown when the MediaDrm instance has become unusable
+ * due to a restart of the mediaserver process. To continue, the app must
+ * release the MediaDrm object, then create and initialize a new one.
+ */
+public class MediaDrmResetException extends IllegalStateException {
+ public MediaDrmResetException(String detailMessage) {
+ super(detailMessage);
+ }
+}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 13714d3..6dd855d 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -3264,6 +3264,13 @@
/** Some operation takes too long to complete, usually more than 3-5 seconds. */
public static final int MEDIA_ERROR_TIMED_OUT = -110;
+ /** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
+ * system/core/include/utils/Errors.h
+ * @see android.media.MediaPlayer.OnErrorListener
+ * @hide
+ */
+ public static final int MEDIA_ERROR_SYSTEM = -2147483648;
+
/**
* Interface definition of a callback to be invoked when there
* has been an error during an asynchronous operation (other errors
@@ -3287,6 +3294,7 @@
* <li>{@link #MEDIA_ERROR_MALFORMED}
* <li>{@link #MEDIA_ERROR_UNSUPPORTED}
* <li>{@link #MEDIA_ERROR_TIMED_OUT}
+ * <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error.
* </ul>
* @return True if the method handled the error, false if it didn't.
* Returning false, or not having an OnErrorListener at all, will
@@ -3346,6 +3354,14 @@
*/
public static final int MEDIA_INFO_BUFFERING_END = 702;
+ /** Estimated network bandwidth information (kbps) is available; currently this event fires
+ * simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
+ * when playing network files.
+ * @see android.media.MediaPlayer.OnInfoListener
+ * @hide
+ */
+ public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
+
/** Bad interleaving means that a media has been improperly interleaved or
* not interleaved at all, e.g has all the video samples first then all the
* audio ones. Video is playing but a lot of disk seeks may be happening.
@@ -3403,6 +3419,8 @@
* <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
* <li>{@link #MEDIA_INFO_BUFFERING_START}
* <li>{@link #MEDIA_INFO_BUFFERING_END}
+ * <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> -
+ * bandwidth information is available (as <code>extra</code> kbps)
* <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
* <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
* <li>{@link #MEDIA_INFO_METADATA_UPDATE}
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index 7998a92..93fb6d2 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -50,21 +50,43 @@
* Close this object to terminate the connection.
*/
public class MidiConnection implements Closeable {
- private final IBinder mToken;
- private final MidiInputPort mInputPort;
+ private final IMidiDeviceServer mInputPortDeviceServer;
+ private final IBinder mInputPortToken;
+ private final IBinder mOutputPortToken;
+ private final CloseGuard mGuard = CloseGuard.get();
+ private boolean mIsClosed;
- MidiConnection(IBinder token, MidiInputPort inputPort) {
- mToken = token;
- mInputPort = inputPort;
+ MidiConnection(IBinder outputPortToken, MidiInputPort inputPort) {
+ mInputPortDeviceServer = inputPort.getDeviceServer();
+ mInputPortToken = inputPort.getToken();
+ mOutputPortToken = outputPortToken;
+ mGuard.open("close");
}
@Override
public void close() throws IOException {
+ synchronized (mGuard) {
+ if (mIsClosed) return;
+ mGuard.close();
+ try {
+ // close input port
+ mInputPortDeviceServer.closePort(mInputPortToken);
+ // close output port
+ mDeviceServer.closePort(mOutputPortToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in MidiConnection.close");
+ }
+ mIsClosed = true;
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
try {
- mDeviceServer.closePort(mToken);
- IoUtils.closeQuietly(mInputPort);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in MidiConnection.close");
+ mGuard.warnIfOpen();
+ close();
+ } finally {
+ super.finalize();
}
}
}
diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java
index 1212b64..19ff624 100644
--- a/media/java/android/media/midi/MidiDeviceServer.java
+++ b/media/java/android/media/midi/MidiDeviceServer.java
@@ -257,7 +257,14 @@
public void connectPorts(IBinder token, ParcelFileDescriptor pfd,
int outputPortNumber) {
MidiInputPort inputPort = new MidiInputPort(pfd, outputPortNumber);
- mOutputPortDispatchers[outputPortNumber].getSender().connect(inputPort);
+ MidiDispatcher dispatcher = mOutputPortDispatchers[outputPortNumber];
+ synchronized (dispatcher) {
+ dispatcher.getSender().connect(inputPort);
+ int openCount = dispatcher.getReceiverCount();
+ mOutputPortOpenCount[outputPortNumber] = openCount;
+ updateDeviceStatus();
+ }
+
mInputPorts.add(inputPort);
OutputPortClient client = new OutputPortClient(token, inputPort);
synchronized (mPortClients) {
diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java
index af5a86c..db41b10 100644
--- a/media/java/android/media/midi/MidiInputPort.java
+++ b/media/java/android/media/midi/MidiInputPort.java
@@ -103,17 +103,33 @@
// used by MidiDevice.connectInputPort() to connect our socket directly to another device
/* package */ ParcelFileDescriptor claimFileDescriptor() {
- synchronized (mBuffer) {
- ParcelFileDescriptor pfd = mParcelFileDescriptor;
- if (pfd != null) {
+ synchronized (mGuard) {
+ ParcelFileDescriptor pfd;
+ synchronized (mBuffer) {
+ pfd = mParcelFileDescriptor;
+ if (pfd == null) return null;
IoUtils.closeQuietly(mOutputStream);
mParcelFileDescriptor = null;
mOutputStream = null;
}
+
+ // Set mIsClosed = true so we will not call mDeviceServer.closePort() in close().
+ // MidiDevice.MidiConnection.close() will do the cleanup instead.
+ mIsClosed = true;
return pfd;
}
}
+ // used by MidiDevice.MidiConnection to close this port after the connection is closed
+ /* package */ IBinder getToken() {
+ return mToken;
+ }
+
+ // used by MidiDevice.MidiConnection to close this port after the connection is closed
+ /* package */ IMidiDeviceServer getDeviceServer() {
+ return mDeviceServer;
+ }
+
@Override
public void close() throws IOException {
synchronized (mGuard) {
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 91b1a49..7cd086e 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
+import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.provider.BaseColumns;
@@ -281,12 +282,12 @@
return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
}
- private static final boolean isTvUri(Uri uri) {
+ private static boolean isTvUri(Uri uri) {
return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())
&& AUTHORITY.equals(uri.getAuthority());
}
- private static final boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) {
+ private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) {
List<String> pathSegments = uri.getPathSegments();
return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0));
}
@@ -332,15 +333,15 @@
*/
public interface BaseTvColumns extends BaseColumns {
/**
- * The name of the package that owns a row in each table.
+ * The name of the package that owns the current row.
*
- * <p>The TV provider fills it in with the name of the package that provides the initial data
- * of that row. If the package is later uninstalled, the rows it owns are automatically
- * removed from the tables.
+ * <p>The TV provider fills in this column with the name of the package that provides the
+ * initial data of the row. If the package is later uninstalled, the rows it owns are
+ * automatically removed from the tables.
*
* <p>Type: TEXT
*/
- public static final String COLUMN_PACKAGE_NAME = "package_name";
+ String COLUMN_PACKAGE_NAME = "package_name";
}
/** Column definitions for the TV channels table. */
@@ -564,7 +565,7 @@
* defined there (e.g. ETSI EN 300 468/TR 101 211 and ARIB STD-B10). If channels cannot be
* globally identified by 2-tuple {{@link #COLUMN_TRANSPORT_STREAM_ID},
* {@link #COLUMN_SERVICE_ID}}, one must carefully assign a value to this field to form a
- * unique 3-tuple identification {{@link #COLUMN_ORIGINAL_NETWORK_ID},
+ * unique 3-tuple identification {{@code COLUMN_ORIGINAL_NETWORK_ID},
* {@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}} for its channels.
*
* <p>This is a required field if the channel cannot be uniquely identified by a 2-tuple
@@ -680,12 +681,13 @@
/**
* The flag indicating whether this TV channel is searchable or not.
*
- * <p>In some regions, it is not allowed to surface search results for a given channel
- * without broadcaster's consent. This is used to impose such restriction. Channels marked
- * with "not searchable" cannot be used by other services except for the system service that
- * shows the TV content. A value of 1 indicates the channel is searchable and can be
- * included in search results, a value of 0 indicates the channel and its TV programs are
- * hidden from search. If not specified, this value is set to 1 (searchable) by default.
+ * <p>The columns of searchable channels can be read by other applications that have proper
+ * permission. Care must be taken not to open sensitive data.
+ *
+ * <p>A value of 1 indicates that the channel is searchable and its columns can be read by
+ * other applications, a value of 0 indicates that the channel is hidden and its columns can
+ * be read only by the package that owns the channel and the system. If not specified, this
+ * value is set to 1 (searchable) by default.
*
* <p>Type: INTEGER (boolean)
*/
@@ -708,6 +710,110 @@
public static final String COLUMN_LOCKED = "locked";
/**
+ * 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
+ * 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>The app-linking allows channel input sources to provide activity links from their live
+ * channel programming to another activity. This enables content providers to increase user
+ * engagement by offering the viewer other content or actions.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_APP_LINK_COLOR
+ * @see #COLUMN_APP_LINK_INTENT_URI
+ * @see #COLUMN_APP_LINK_POSTER_ART_URI
+ * @see #COLUMN_APP_LINK_TEXT
+ */
+ public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+
+ /**
+ * 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:
+ *
+ * <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>The app-linking allows channel input sources to provide activity links from their live
+ * channel programming to another activity. This enables content providers to increase user
+ * engagement by offering the viewer other content or actions.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_APP_LINK_COLOR
+ * @see #COLUMN_APP_LINK_ICON_URI
+ * @see #COLUMN_APP_LINK_INTENT_URI
+ * @see #COLUMN_APP_LINK_TEXT
+ */
+ public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+
+ /**
+ * The link text of the app link template for this channel.
+ *
+ * <p>This provides a short description of the action that happens when the corresponding
+ * app link is clicked.
+ *
+ * <p>The app-linking allows channel input sources to provide activity links from their live
+ * channel programming to another activity. This enables content providers to increase user
+ * engagement by offering the viewer other content or actions.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_APP_LINK_COLOR
+ * @see #COLUMN_APP_LINK_ICON_URI
+ * @see #COLUMN_APP_LINK_INTENT_URI
+ * @see #COLUMN_APP_LINK_POSTER_ART_URI
+ */
+ public static final String COLUMN_APP_LINK_TEXT = "app_link_text";
+
+ /**
+ * The accent color of the app link template for this channel. This is primarily used for
+ * the background color of the text box in the template.
+ *
+ * <p>The app-linking allows channel input sources to provide activity links from their live
+ * channel programming to another activity. This enables content providers to increase user
+ * engagement by offering the viewer other content or actions.
+ *
+ * <p>Type: INTEGER (color value)
+ * @see #COLUMN_APP_LINK_ICON_URI
+ * @see #COLUMN_APP_LINK_INTENT_URI
+ * @see #COLUMN_APP_LINK_POSTER_ART_URI
+ * @see #COLUMN_APP_LINK_TEXT
+ */
+ public static final String COLUMN_APP_LINK_COLOR = "app_link_color";
+
+ /**
+ * The intent URI of the app link for this channel.
+ *
+ * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+ * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+ * launched when the user clicks the corresponding app link for the current channel.
+ *
+ * <p>The app-linking allows channel input sources to provide activity links from their live
+ * channel programming to another activity. This enables content providers to increase user
+ * engagement by offering the viewer other content or actions.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_APP_LINK_COLOR
+ * @see #COLUMN_APP_LINK_ICON_URI
+ * @see #COLUMN_APP_LINK_POSTER_ART_URI
+ * @see #COLUMN_APP_LINK_TEXT
+ */
+ public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+
+ /**
* Internal data used by individual TV input services.
*
* <p>This is internal to the provider that inserted it, and should not be decoded by other
@@ -995,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
@@ -1004,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
@@ -1011,6 +1139,21 @@
public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
/**
+ * The flag indicating whether this TV program is searchable or not.
+ *
+ * <p>The columns of searchable programs can be read by other applications that have proper
+ * permission. Care must be taken not to open sensitive data.
+ *
+ * <p>A value of 1 indicates that the program is searchable and its columns can be read by
+ * other applications, a value of 0 indicates that the program is hidden and its columns can
+ * be read only by the package that owns the program and the system. If not specified, this
+ * value is set to 1 (searchable) by default.
+ *
+ * <p>Type: INTEGER (boolean)
+ */
+ public static final String COLUMN_SEARCHABLE = "searchable";
+
+ /**
* Internal data used by individual TV input services.
*
* <p>This is internal to the provider that inserted it, and should not be decoded by other
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 5d1aa14..ce72c2f 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -106,7 +106,7 @@
*/
public static final String EXTRA_INPUT_ID = "android.media.tv.extra.INPUT_ID";
- private static SparseIntArray sHardwareTypeToTvInputType = new SparseIntArray();
+ private static final SparseIntArray sHardwareTypeToTvInputType = new SparseIntArray();
private static final String XML_START_TAG_NAME = "tv-input";
private static final String DELIMITER_INFO_IN_ID = "/";
@@ -594,7 +594,7 @@
* @param name the component name for generating an input id.
* @return the generated input id for the given {@code name}.
*/
- private static final String generateInputIdForComponentName(ComponentName name) {
+ private static String generateInputIdForComponentName(ComponentName name) {
return name.flattenToShortString();
}
@@ -605,7 +605,7 @@
* @param deviceInfo HdmiDeviceInfo describing this TV input.
* @return the generated input id for the given {@code name} and {@code deviceInfo}.
*/
- private static final String generateInputIdForHdmiDevice(
+ private static String generateInputIdForHdmiDevice(
ComponentName name, HdmiDeviceInfo deviceInfo) {
// Example of the format : "/HDMI%04X%02X"
String format = DELIMITER_INFO_IN_ID + PREFIX_HDMI_DEVICE
@@ -622,7 +622,7 @@
* @param hardwareInfo TvInputHardwareInfo describing this TV input.
* @return the generated input id for the given {@code name} and {@code hardwareInfo}.
*/
- private static final String generateInputIdForHardware(
+ private static String generateInputIdForHardware(
ComponentName name, TvInputHardwareInfo hardwareInfo) {
return name.flattenToShortString() + DELIMITER_INFO_IN_ID + PREFIX_HARDWARE_DEVICE
+ hardwareInfo.getDeviceId();
@@ -648,13 +648,13 @@
mSetupActivity = in.readString();
mSettingsActivity = in.readString();
mType = in.readInt();
- mIsHardwareInput = in.readByte() == 1 ? true : false;
+ mIsHardwareInput = in.readByte() == 1;
mHdmiDeviceInfo = in.readParcelable(null);
mIcon = in.readParcelable(null);
mIconUri = in.readParcelable(null);
mLabelRes = in.readInt();
mLabel = in.readString();
- mIsConnectedToHdmiSwitch = in.readByte() == 1 ? true : false;
+ mIsConnectedToHdmiSwitch = in.readByte() == 1;
}
/**
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 01de898..e9c94c0 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -29,6 +29,7 @@
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pools.Pool;
@@ -1652,14 +1653,16 @@
*/
boolean updateTrackSelection(int type, String trackId) {
synchronized (mMetadataLock) {
- if (type == TvTrackInfo.TYPE_AUDIO && trackId != mSelectedAudioTrackId) {
+ if (type == TvTrackInfo.TYPE_AUDIO
+ && !TextUtils.equals(trackId, mSelectedAudioTrackId)) {
mSelectedAudioTrackId = trackId;
return true;
- } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != mSelectedVideoTrackId) {
+ } else if (type == TvTrackInfo.TYPE_VIDEO
+ && !TextUtils.equals(trackId, mSelectedVideoTrackId)) {
mSelectedVideoTrackId = trackId;
return true;
} else if (type == TvTrackInfo.TYPE_SUBTITLE
- && trackId != mSelectedSubtitleTrackId) {
+ && !TextUtils.equals(trackId, mSelectedSubtitleTrackId)) {
mSelectedSubtitleTrackId = trackId;
return true;
}
@@ -1929,7 +1932,7 @@
* @param handled {@code true} if the dispatched input event was handled properly.
* {@code false} otherwise.
*/
- public void onFinishedInputEvent(Object token, boolean handled);
+ void onFinishedInputEvent(Object token, boolean handled);
}
// Must be called on the main looper
@@ -1978,7 +1981,7 @@
mPendingEvents.removeAt(index);
if (timeout) {
- Log.w(TAG, "Timeout waiting for seesion to handle input event after "
+ Log.w(TAG, "Timeout waiting for session to handle input event after "
+ INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken);
} else {
mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p);
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index f52ccc9..35037bb 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -233,10 +233,7 @@
mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
}
TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
- if (info != null && info.isPassthroughInput()) {
- return true;
- }
- return false;
+ return info != null && info.isPassthroughInput();
}
/**
@@ -1383,7 +1380,7 @@
}
}
- private final void executeOrPostRunnable(Runnable action) {
+ private void executeOrPostRunnable(Runnable action) {
synchronized(mLock) {
if (mSessionCallback == null) {
// The session is not initialized yet.
@@ -1651,13 +1648,13 @@
if (sessionImpl instanceof HardwareSession) {
HardwareSession proxySession =
((HardwareSession) sessionImpl);
- String harewareInputId = proxySession.getHardwareInputId();
- if (TextUtils.isEmpty(harewareInputId) ||
- !isPassthroughInput(harewareInputId)) {
- if (TextUtils.isEmpty(harewareInputId)) {
+ String hardwareInputId = proxySession.getHardwareInputId();
+ if (TextUtils.isEmpty(hardwareInputId) ||
+ !isPassthroughInput(hardwareInputId)) {
+ if (TextUtils.isEmpty(hardwareInputId)) {
Log.w(TAG, "Hardware input id is not setup yet.");
} else {
- Log.w(TAG, "Invalid hardware input id : " + harewareInputId);
+ Log.w(TAG, "Invalid hardware input id : " + hardwareInputId);
}
sessionImpl.onRelease();
try {
@@ -1672,7 +1669,7 @@
proxySession.mServiceHandler = mServiceHandler;
TvInputManager manager = (TvInputManager) getSystemService(
Context.TV_INPUT_SERVICE);
- manager.createSession(harewareInputId,
+ manager.createSession(hardwareInputId,
proxySession.mHardwareSessionCallback, mServiceHandler);
} else {
SomeArgs someArgs = SomeArgs.obtain();
diff --git a/media/java/android/media/tv/TvStreamConfig.java b/media/java/android/media/tv/TvStreamConfig.java
index 1bdc63e..0c2f3fe 100644
--- a/media/java/android/media/tv/TvStreamConfig.java
+++ b/media/java/android/media/tv/TvStreamConfig.java
@@ -89,12 +89,8 @@
@Override
public String toString() {
- StringBuilder b = new StringBuilder(128);
- b.append("TvStreamConfig {");
- b.append("mStreamId=").append(mStreamId).append(";");
- b.append("mType=").append(mType).append(";");
- b.append("mGeneration=").append(mGeneration).append("}");
- return b.toString();
+ return "TvStreamConfig {mStreamId=" + mStreamId + ";" + "mType=" + mType + ";mGeneration="
+ + mGeneration + "}";
}
// Parcelable
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index e7ce1dd..003a274 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -191,7 +191,7 @@
* the active source.
*
* <p>First tuned {@link TvView} becomes main automatically, and keeps to be main until either
- * {@link #reset} is called for the main {@link TvView} or {@link #setMain} is called for other
+ * {@link #reset} is called for the main {@link TvView} or {@code setMain()} is called for other
* {@link TvView}.
* @hide
*/
@@ -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,8 +341,14 @@
}
private void resetInternal() {
+ mSessionCallback = null;
+ mPendingAppPrivateCommands.clear();
if (mSession != null) {
- release();
+ setSessionSurface(null);
+ removeSessionOverlayView();
+ mUseRequestedSurfaceLayout = false;
+ mSession.release();
+ mSession = null;
resetSurfaceView();
}
}
@@ -738,17 +748,6 @@
addView(mSurfaceView);
}
- private void release() {
- mPendingAppPrivateCommands.clear();
-
- setSessionSurface(null);
- removeSessionOverlayView();
- mUseRequestedSurfaceLayout = false;
- mSession.release();
- mSession = null;
- mSessionCallback = null;
- }
-
private void setSessionSurface(Surface surface) {
if (mSession == null) {
return;
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 635fa11..0034b07 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -1240,8 +1240,11 @@
return static_cast<jint>(PublicFormat::PRIVATE);
} else {
CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+ int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat(
+ static_cast<PublicFormat>(readerFormat));
+ int32_t fmt = applyFormatOverrides(buffer->flexFormat, readerHalFormat);
PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat(
- buffer->flexFormat, buffer->dataSpace);
+ fmt, buffer->dataSpace);
return static_cast<jint>(publicFmt);
}
}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index d456dc10..9ec0312 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -308,6 +308,10 @@
} else if (err == ERROR_DRM_DEVICE_REVOKED) {
jniThrowException(env, "android/media/DeniedByServerException", msg);
return true;
+ } else if (err == DEAD_OBJECT) {
+ jniThrowException(env, "android/media/MediaDrmResetException",
+ "mediaserver died");
+ return true;
} else if (err != OK) {
String8 errbuf;
if (drmMessage != NULL) {
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index fdc586b..aba4bbe 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -472,6 +472,8 @@
if (lpJniStorage) {
ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
+ env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
+ env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);
delete lpJniStorage;
}
}
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 6098b4a4..0557019 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -450,6 +450,8 @@
if (lpJniStorage) {
ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
+ env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_class);
+ env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_ref);
delete lpJniStorage;
}
}
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 540a38b..0608d27 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="title_open" msgid="4353228937663917801">"Maak oop vanaf"</string>
+ <string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Skep vouer"</string>
<string name="menu_grid" msgid="6878021334497835259">"Roosteraansig"</string>
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
index 0b03a94..d7c031e 100644
--- a/packages/DocumentsUI/res/values-sw720dp/styles.xml
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="DialogWhenReallyLarge" parent="@*android:style/Theme.Material.DayNight.Dialog">
+ <style name="DialogWhenReallyLarge" parent="@*android:style/Theme.DeviceDefault.Light.Dialog">
<!-- We do not specify width of window here because the max size of
floating window specified by windowFixedWidthis is limited. -->
<item name="*android:windowFixedHeightMajor">80%</item>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index ca43a7e..bc822fb 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -53,7 +53,7 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"குறுக்குவழிகள்"</string>
<string name="root_type_device" msgid="7121342474653483538">"சாதனங்கள்"</string>
<string name="root_type_apps" msgid="8838065367985945189">"மேலும் பயன்பாடுகள்"</string>
- <string name="empty" msgid="7858882803708117596">"உருப்படிகள் இல்லை"</string>
+ <string name="empty" msgid="7858882803708117596">"எதுவும் இல்லை"</string>
<string name="toast_no_application" msgid="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
<string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 6d741aa..8c4b777 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="DialogWhenReallyLarge" parent="@android:style/Theme.Material.DayNight.DarkActionBar" />
+ <style name="DialogWhenReallyLarge" parent="@android:style/Theme.DeviceDefault.Light.DarkActionBar" />
<style name="DocumentsTheme" parent="@style/DialogWhenReallyLarge">
<item name="android:actionBarWidgetTheme">@null</item>
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/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index aa99a7b..0c6837f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -216,6 +216,19 @@
return mCallback;
}
+ @Override
+ public void showPromptReason(int reason) {
+ if (reason != PROMPT_REASON_NONE) {
+ int promtReasonStringRes = getPromtReasonStringRes(reason);
+ if (promtReasonStringRes != 0) {
+ mSecurityMessageDisplay.setMessage(promtReasonStringRes,
+ true /* important */);
+ }
+ }
+ }
+
+ protected abstract int getPromtReasonStringRes(int reason);
+
// Cause a VIRTUAL_KEY vibration
public void doHapticKeyClick() {
if (mEnableHaptics) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
index 10baf23..e5f3dc9 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
@@ -25,6 +25,6 @@
* Turns on debugging information for the whole Keyguard. This is very verbose and should only
* be used temporarily for debugging.
*/
- public static final boolean DEBUG = true;
- public static final boolean DEBUG_SIM_STATES = true;
+ public static final boolean DEBUG = false;
+ public static final boolean DEBUG_SIM_STATES = false;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index cd4b24a..ff4e815 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -160,6 +160,17 @@
}
/**
+ * Show a string explaining why the security view needs to be solved.
+ *
+ * @param reason a flag indicating which string should be shown, see
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE}
+ * and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}
+ */
+ public void showPromptReason(int reason) {
+ mSecurityContainer.showPromptReason(reason);
+ }
+
+ /**
* Dismisses the keyguard by going to the next screen or making it gone.
*
* @return True if the keyguard is done.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index ac9dc85..d265e0d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -50,7 +50,7 @@
mAppearAnimationUtils = new AppearAnimationUtils(context);
mDisappearAnimationUtils = new DisappearAnimationUtils(context,
125, 0.6f /* translationScale */,
- 0.6f /* delayScale */, AnimationUtils.loadInterpolator(
+ 0.45f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index c9ad728..2db87b3 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -111,6 +111,16 @@
}
@Override
+ protected int getPromtReasonStringRes(int reason) {
+ switch (reason) {
+ case PROMPT_REASON_RESTART:
+ return R.string.kg_prompt_reason_restart_password;
+ default:
+ return 0;
+ }
+ }
+
+ @Override
public void onPause() {
super.onPause();
mImm.hideSoftInputFromWindow(getWindowToken(), 0);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 1bd0bb4..3568429 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -85,10 +85,9 @@
}
};
private Rect mTempRect = new Rect();
- private SecurityMessageDisplay mSecurityMessageDisplay;
+ private KeyguardMessageArea mSecurityMessageDisplay;
private View mEcaView;
private ViewGroup mContainer;
- private KeyguardMessageArea mHelpMessage;
private int mDisappearYTranslation;
enum FooterMode {
@@ -110,7 +109,7 @@
mContext, android.R.interpolator.linear_out_slow_in));
mDisappearAnimationUtils = new DisappearAnimationUtils(context,
125, 1.2f /* translationScale */,
- 0.8f /* delayScale */, AnimationUtils.loadInterpolator(
+ 0.6f /* delayScale */, AnimationUtils.loadInterpolator(
mContext, android.R.interpolator.fast_out_linear_in));
mDisappearYTranslation = getResources().getDimensionPixelSize(
R.dimen.disappear_y_translation);
@@ -141,10 +140,10 @@
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
- mSecurityMessageDisplay = KeyguardMessageArea.findSecurityMessageDisplay(this);
+ mSecurityMessageDisplay =
+ (KeyguardMessageArea) KeyguardMessageArea.findSecurityMessageDisplay(this);
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
mContainer = (ViewGroup) findViewById(R.id.container);
- mHelpMessage = (KeyguardMessageArea) findViewById(R.id.keyguard_message_area);
EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
if (button != null) {
@@ -320,6 +319,17 @@
}
@Override
+ public void showPromptReason(int reason) {
+ switch (reason) {
+ case PROMPT_REASON_RESTART:
+ mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_restart_pattern,
+ true /* important */);
+ break;
+ default:
+ }
+ }
+
+ @Override
public void startAppearAnimation() {
enableClipping(false);
setAlpha(1f);
@@ -337,8 +347,8 @@
}
},
this);
- if (!TextUtils.isEmpty(mHelpMessage.getText())) {
- mAppearAnimationUtils.createAnimation(mHelpMessage, 0,
+ if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
+ mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
mAppearAnimationUtils.getStartTranslation(),
true /* appearing */,
@@ -366,8 +376,8 @@
}
}
}, KeyguardPatternView.this);
- if (!TextUtils.isEmpty(mHelpMessage.getText())) {
- mDisappearAnimationUtils.createAnimation(mHelpMessage, 0,
+ if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
+ mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
200,
- mDisappearAnimationUtils.getStartTranslation() * 3,
false /* appearing */,
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 23834a3..07947b1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -93,6 +93,16 @@
return super.onKeyDown(keyCode, event);
}
+ @Override
+ protected int getPromtReasonStringRes(int reason) {
+ switch (reason) {
+ case PROMPT_REASON_RESTART:
+ return R.string.kg_prompt_reason_restart_pin;
+ default:
+ return 0;
+ }
+ }
+
private void performClick(View view) {
view.performClick();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index d17b25a..23bd238 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -329,7 +329,9 @@
case SimPuk:
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode();
- if (securityMode != SecurityMode.None) {
+ if (securityMode != SecurityMode.None
+ || !mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser())) {
showSecurityScreen(securityMode);
} else {
finish = true;
@@ -509,6 +511,13 @@
}
@Override
+ public void showPromptReason(int reason) {
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ getSecurityView(mCurrentSecuritySelection).showPromptReason(reason);
+ }
+ }
+
+ @Override
public void showUsabilityHint() {
mSecurityViewFlipper.showUsabilityHint();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
index 5b50236..5658a74 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -21,6 +21,9 @@
static public final int SCREEN_ON = 1;
static public final int VIEW_REVEALED = 2;
+ int PROMPT_REASON_NONE = 0;
+ int PROMPT_REASON_RESTART = 1;
+
/**
* Interface back to keyguard to tell it when security
* @param callback
@@ -66,6 +69,14 @@
KeyguardSecurityCallback getCallback();
/**
+ * Show a string explaining why the security view needs to be solved.
+ *
+ * @param reason a flag indicating which string should be shown, see {@link #PROMPT_REASON_NONE}
+ * and {@link #PROMPT_REASON_RESTART}
+ */
+ void showPromptReason(int reason);
+
+ /**
* Instruct the view to show usability hints, if any.
*
*/
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index 54467f3..a0ff21b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -131,6 +131,14 @@
}
@Override
+ public void showPromptReason(int reason) {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.showPromptReason(reason);
+ }
+ }
+
+ @Override
public void showUsabilityHint() {
KeyguardSecurityView ksv = getSecurityView();
if (ksv != null) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index f4acff8..aeac912 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -95,6 +95,12 @@
}
}
+ @Override
+ protected int getPromtReasonStringRes(int reason) {
+ // No message on SIM Pin
+ return 0;
+ }
+
private String getPinPasswordErrorMessage(int attemptsRemaining) {
String displayMessage;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index b85d966..af88239 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -140,6 +140,12 @@
}
}
+ @Override
+ protected int getPromtReasonStringRes(int reason) {
+ // No message on SIM Puk
+ return 0;
+ }
+
private String getPukPasswordErrorMessage(int attemptsRemaining) {
String displayMessage;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 273f166..022338d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -804,8 +804,7 @@
private void startListeningForFingerprint() {
if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
int userId = ActivityManager.getCurrentUser();
- if (mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
- && mFpm.getEnrolledFingerprints(userId).size() > 0) {
+ if (isUnlockWithFingerPrintPossible(userId)) {
if (mFingerprintCancelSignal != null) {
mFingerprintCancelSignal.cancel();
}
@@ -815,6 +814,11 @@
}
}
+ public boolean isUnlockWithFingerPrintPossible(int userId) {
+ return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
+ && mFpm.getEnrolledFingerprints(userId).size() > 0;
+ }
+
private void stopListeningForFingerprint() {
if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
if (isFingerprintDetectionRunning()) {
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index f5c809a..ff463c6 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -81,4 +81,12 @@
* @return true if the screen is on
*/
boolean isScreenOn();
+
+ /**
+ * @return one of the reasons why the bouncer needs to be shown right now and the user can't use
+ * his normal unlock method like fingerprint or trust agents. See
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE}
+ * and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}.
+ */
+ int getBouncerPromptReason();
}
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 05de5b7..11fa991 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -17,6 +17,9 @@
<resources>
<style name="PrintActivity" parent="@android:style/Theme.DeviceDefault">
+ <item name="android:colorPrimary">@*android:color/material_blue_grey_900</item>
+ <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_950</item>
+ <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java
deleted file mode 100644
index 8b38a5f..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java
+++ /dev/null
@@ -1,192 +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 com.android.settingslib.applications;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class PermissionsInfo {
-
- private static final String TAG = "PermissionsInfo";
-
- private final PackageManager mPm;
- private final ArrayList<PermissionGroup> mGroups = new ArrayList<>();
- private final Map<String, PermissionGroup> mGroupLookup = new ArrayMap<>();
- private final Callback mCallback;
- private final Context mContext;
- // Count of apps that request runtime permissions.
- private int mRuntimePermAppsCt;
- // Count of apps that are granted runtime permissions.
- private int mRuntimePermAppsGrantedCt;
-
- public PermissionsInfo(Context context, Callback callback) {
- mContext = context;
- mPm = context.getPackageManager();
- mCallback = callback;
- new PermissionsLoader().execute();
- }
-
- public List<PermissionGroup> getGroups() {
- synchronized (mGroups) {
- return new ArrayList<>(mGroups);
- }
- }
-
- public int getRuntimePermAppsCount() {
- return mRuntimePermAppsCt;
- }
-
- public int getRuntimePermAppsGrantedCount() {
- return mRuntimePermAppsGrantedCt;
- }
-
- private PermissionGroup getOrCreateGroup(String permission) {
- PermissionGroup group = mGroupLookup.get(permission);
- if (group == null) {
- // Some permissions don't have a group, in that case treat them like a group
- // and create their own PermissionGroup (only if they are runtime).
- try {
- PermissionInfo info = mPm.getPermissionInfo(permission, 0);
- if (info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
- group = new PermissionGroup();
- // TODO: Add default permission icon.
- group.icon = info.icon != 0 ? info.loadIcon(mPm) : mContext.getDrawable(
- com.android.internal.R.drawable.ic_perm_device_info);
- group.name = info.name;
- group.packageName = info.packageName;
- group.label = info.loadLabel(mPm).toString();
- mGroups.add(group);
- mGroupLookup.put(permission, group);
- }
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Unknown permission " + permission, e);
- }
- }
- return group;
- }
-
- private class PermissionsLoader extends AsyncTask<Void, Void, Void> {
-
- @Override
- protected Void doInBackground(Void... params) {
- List<PermissionGroupInfo> groups =
- mPm.getAllPermissionGroups(PackageManager.GET_META_DATA);
- // Get the groups.
- for (PermissionGroupInfo groupInfo : groups) {
- PermissionGroup group = new PermissionGroup();
- // TODO: Add default permission icon.
- group.icon = groupInfo.icon != 0 ? groupInfo.loadIcon(mPm) : mContext.getDrawable(
- com.android.internal.R.drawable.ic_perm_device_info);
- group.name = groupInfo.name;
- group.packageName = groupInfo.packageName;
- group.label = groupInfo.loadLabel(mPm).toString();
- synchronized (mGroups) {
- mGroups.add(group);
- }
- }
- // Load permissions and which are runtime.
- for (PermissionGroup group : mGroups) {
- try {
- List<PermissionInfo> permissions =
- mPm.queryPermissionsByGroup(group.name, 0);
- for (PermissionInfo info : permissions) {
- if (info.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS) continue;
- mGroupLookup.put(info.name, group);
- }
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Problem getting permissions", e);
- }
- }
- // Load granted info.
- for (UserHandle user : UserManager.get(mContext).getUserProfiles()) {
- List<PackageInfo> allApps = mPm.getInstalledPackages(
- PackageManager.GET_PERMISSIONS, user.getIdentifier());
- for (PackageInfo info : allApps) {
- if (info.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1
- || info.requestedPermissions == null) {
- continue;
- }
- final int N = info.requestedPermissionsFlags.length;
- boolean appHasRuntimePerms = false;
- boolean appGrantedRuntimePerms = false;
- for (int i = 0; i < N; i++) {
- boolean granted = (info.requestedPermissionsFlags[i]
- & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
- PermissionGroup group = getOrCreateGroup(info.requestedPermissions[i]);
- String key = Integer.toString(info.applicationInfo.uid);
- if (group != null && !group.possibleApps.contains(key)) {
- appHasRuntimePerms = true;
- group.possibleApps.add(key);
- if (granted) {
- appGrantedRuntimePerms = true;
- group.grantedApps.add(key);
- }
- }
- }
- if (appHasRuntimePerms) {
- mRuntimePermAppsCt++;
- if (appGrantedRuntimePerms) {
- mRuntimePermAppsGrantedCt++;
- }
- }
- }
- }
- Collections.sort(mGroups);
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- mCallback.onPermissionLoadComplete();
- }
- }
-
- public static class PermissionGroup implements Comparable<PermissionGroup> {
- public final List<String> possibleApps = new ArrayList<>();
- public final List<String> grantedApps = new ArrayList<>();
- public String name;
- public String packageName;
- public String label;
- public Drawable icon;
-
- @Override
- public int compareTo(PermissionGroup another) {
- return label.compareTo(another.label);
- }
- }
-
- public interface Callback {
- void onPermissionLoadComplete();
- }
-
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 9a2f71c..bf92fda 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -93,6 +93,7 @@
addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
+ addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler());
// Pairing broadcasts
addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b0429ef..249eaa5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -808,7 +808,7 @@
// The pairing dialog now warns of phone-book access for paired devices.
// No separate prompt is displayed after pairing.
if (getPhonebookPermissionChoice() == CachedBluetoothDevice.ACCESS_UNKNOWN) {
- setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_ALLOWED);
+ setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_REJECTED);
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 4cef286..9325246 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -46,6 +46,7 @@
import com.android.settingslib.R;
+import java.util.ArrayList;
import java.util.Map;
@@ -79,10 +80,15 @@
* For now this data is used only with Verbose Logging so as to show the band and number
* of BSSIDs on which that network is seen.
*/
- public LruCache<String, ScanResult> mScanResultCache;
+ public LruCache<String, ScanResult> mScanResultCache = new LruCache<String, ScanResult>(32);
+
private static final String KEY_NETWORKINFO = "key_networkinfo";
private static final String KEY_WIFIINFO = "key_wifiinfo";
private static final String KEY_SCANRESULT = "key_scanresult";
+ private static final String KEY_SSID = "key_ssid";
+ private static final String KEY_SECURITY = "key_security";
+ private static final String KEY_PSKTYPE = "key_psktype";
+ private static final String KEY_SCANRESULTCACHE = "key_scanresultcache";
private static final String KEY_CONFIG = "key_config";
/**
@@ -108,7 +114,6 @@
private int pskType = PSK_UNKNOWN;
private WifiConfiguration mConfig;
- private ScanResult mScanResult;
private int mRssi = Integer.MAX_VALUE;
private long mSeen = 0;
@@ -125,20 +130,35 @@
if (mConfig != null) {
loadConfig(mConfig);
}
- mScanResult = (ScanResult) savedState.getParcelable(KEY_SCANRESULT);
- if (mScanResult != null) {
- loadResult(mScanResult);
+ if (savedState.containsKey(KEY_SSID)) {
+ ssid = savedState.getString(KEY_SSID);
+ }
+ if (savedState.containsKey(KEY_SECURITY)) {
+ security = savedState.getInt(KEY_SECURITY);
+ }
+ if (savedState.containsKey(KEY_PSKTYPE)) {
+ pskType = savedState.getInt(KEY_PSKTYPE);
}
mInfo = (WifiInfo) savedState.getParcelable(KEY_WIFIINFO);
if (savedState.containsKey(KEY_NETWORKINFO)) {
mNetworkInfo = savedState.getParcelable(KEY_NETWORKINFO);
}
+ if (savedState.containsKey(KEY_SCANRESULTCACHE)) {
+ ArrayList<ScanResult> scanResultArrayList =
+ savedState.getParcelableArrayList(KEY_SCANRESULTCACHE);
+ mScanResultCache.evictAll();
+ for (ScanResult result : scanResultArrayList) {
+ mScanResultCache.put(result.BSSID, result);
+ }
+ }
update(mInfo, mNetworkInfo);
+ mRssi = getRssi();
+ mSeen = getSeen();
}
AccessPoint(Context context, ScanResult result) {
mContext = context;
- loadResult(result);
+ initWithScanResult(result);
}
AccessPoint(Context context, WifiConfiguration config) {
@@ -240,6 +260,28 @@
return WifiManager.calculateSignalLevel(mRssi, 4);
}
+ public int getRssi() {
+ int rssi = Integer.MIN_VALUE;
+ for (ScanResult result : mScanResultCache.snapshot().values()) {
+ if (result.level > rssi) {
+ rssi = result.level;
+ }
+ }
+
+ return rssi;
+ }
+
+ public long getSeen() {
+ long seen = 0;
+ for (ScanResult result : mScanResultCache.snapshot().values()) {
+ if (result.timestamp > seen) {
+ seen = result.timestamp;
+ }
+ }
+
+ return seen;
+ }
+
public NetworkInfo getNetworkInfo() {
return mNetworkInfo;
}
@@ -345,7 +387,7 @@
} else if (isActive()) {
// This is the active connection on non-passpoint network
summary.append(getSummary(mContext, getDetailedState(),
- networkId == WifiConfiguration.INVALID_NETWORK_ID));
+ mInfo != null && mInfo.isEphemeral()));
} else if (mConfig != null && mConfig.isPasspoint()) {
String format = mContext.getString(R.string.available_via_passpoint);
summary.append(String.format(format, mConfig.providerFriendlyName));
@@ -455,120 +497,109 @@
visibility.append(String.format("rx=%.1f", mInfo.rxSuccessRate));
}
- if (mScanResultCache != null) {
- int rssi5 = WifiConfiguration.INVALID_RSSI;
- int rssi24 = WifiConfiguration.INVALID_RSSI;
- int num5 = 0;
- int num24 = 0;
- int numBlackListed = 0;
- int n24 = 0; // Number scan results we included in the string
- int n5 = 0; // Number scan results we included in the string
- Map<String, ScanResult> list = mScanResultCache.snapshot();
- // TODO: sort list by RSSI or age
- for (ScanResult result : list.values()) {
- if (result.seen == 0)
- continue;
+ int rssi5 = WifiConfiguration.INVALID_RSSI;
+ int rssi24 = WifiConfiguration.INVALID_RSSI;
+ int num5 = 0;
+ int num24 = 0;
+ int numBlackListed = 0;
+ int n24 = 0; // Number scan results we included in the string
+ int n5 = 0; // Number scan results we included in the string
+ Map<String, ScanResult> list = mScanResultCache.snapshot();
+ // TODO: sort list by RSSI or age
+ for (ScanResult result : list.values()) {
+ if (result.seen == 0)
+ continue;
- if (result.autoJoinStatus != ScanResult.ENABLED) numBlackListed++;
+ if (result.autoJoinStatus != ScanResult.ENABLED) numBlackListed++;
- if (result.frequency >= LOWER_FREQ_5GHZ
- && result.frequency <= HIGHER_FREQ_5GHZ) {
- // Strictly speaking: [4915, 5825]
- // number of known BSSID on 5GHz band
- num5 = num5 + 1;
- } else if (result.frequency >= LOWER_FREQ_24GHZ
- && result.frequency <= HIGHER_FREQ_24GHZ) {
- // Strictly speaking: [2412, 2482]
- // number of known BSSID on 2.4Ghz band
- num24 = num24 + 1;
- }
-
- // Ignore results seen, older than 20 seconds
- if (now - result.seen > VISIBILITY_OUTDATED_AGE_IN_MILLI) continue;
-
- if (result.frequency >= LOWER_FREQ_5GHZ
- && result.frequency <= HIGHER_FREQ_5GHZ) {
- if (result.level > rssi5) {
- rssi5 = result.level;
- }
- if (n5 < 4) {
- if (scans5GHz == null) scans5GHz = new StringBuilder();
- scans5GHz.append(" \n{").append(result.BSSID);
- if (bssid != null && result.BSSID.equals(bssid)) scans5GHz.append("*");
- scans5GHz.append("=").append(result.frequency);
- scans5GHz.append(",").append(result.level);
- if (result.autoJoinStatus != 0) {
- scans5GHz.append(",st=").append(result.autoJoinStatus);
- }
- if (result.numIpConfigFailures != 0) {
- scans5GHz.append(",ipf=").append(result.numIpConfigFailures);
- }
- scans5GHz.append("}");
- n5++;
- }
- } else if (result.frequency >= LOWER_FREQ_24GHZ
- && result.frequency <= HIGHER_FREQ_24GHZ) {
- if (result.level > rssi24) {
- rssi24 = result.level;
- }
- if (n24 < 4) {
- if (scans24GHz == null) scans24GHz = new StringBuilder();
- scans24GHz.append(" \n{").append(result.BSSID);
- if (bssid != null && result.BSSID.equals(bssid)) scans24GHz.append("*");
- scans24GHz.append("=").append(result.frequency);
- scans24GHz.append(",").append(result.level);
- if (result.autoJoinStatus != 0) {
- scans24GHz.append(",st=").append(result.autoJoinStatus);
- }
- if (result.numIpConfigFailures != 0) {
- scans24GHz.append(",ipf=").append(result.numIpConfigFailures);
- }
- scans24GHz.append("}");
- n24++;
- }
- }
+ if (result.frequency >= LOWER_FREQ_5GHZ
+ && result.frequency <= HIGHER_FREQ_5GHZ) {
+ // Strictly speaking: [4915, 5825]
+ // number of known BSSID on 5GHz band
+ num5 = num5 + 1;
+ } else if (result.frequency >= LOWER_FREQ_24GHZ
+ && result.frequency <= HIGHER_FREQ_24GHZ) {
+ // Strictly speaking: [2412, 2482]
+ // number of known BSSID on 2.4Ghz band
+ num24 = num24 + 1;
}
- visibility.append(" [");
- if (num24 > 0) {
- visibility.append("(").append(num24).append(")");
- if (n24 <= 4) {
- if (scans24GHz != null) {
- visibility.append(scans24GHz.toString());
- }
- } else {
- visibility.append("max=").append(rssi24);
- if (scans24GHz != null) {
- visibility.append(",").append(scans24GHz.toString());
- }
+
+ // Ignore results seen, older than 20 seconds
+ if (now - result.seen > VISIBILITY_OUTDATED_AGE_IN_MILLI) continue;
+
+ if (result.frequency >= LOWER_FREQ_5GHZ
+ && result.frequency <= HIGHER_FREQ_5GHZ) {
+ if (result.level > rssi5) {
+ rssi5 = result.level;
}
- }
- visibility.append(";");
- if (num5 > 0) {
- visibility.append("(").append(num5).append(")");
- if (n5 <= 4) {
- if (scans5GHz != null) {
- visibility.append(scans5GHz.toString());
+ if (n5 < 4) {
+ if (scans5GHz == null) scans5GHz = new StringBuilder();
+ scans5GHz.append(" \n{").append(result.BSSID);
+ if (bssid != null && result.BSSID.equals(bssid)) scans5GHz.append("*");
+ scans5GHz.append("=").append(result.frequency);
+ scans5GHz.append(",").append(result.level);
+ if (result.autoJoinStatus != 0) {
+ scans5GHz.append(",st=").append(result.autoJoinStatus);
}
- } else {
- visibility.append("max=").append(rssi5);
- if (scans5GHz != null) {
- visibility.append(",").append(scans5GHz.toString());
+ if (result.numIpConfigFailures != 0) {
+ scans5GHz.append(",ipf=").append(result.numIpConfigFailures);
}
+ scans5GHz.append("}");
+ n5++;
}
- }
- if (numBlackListed > 0)
- visibility.append("!").append(numBlackListed);
- visibility.append("]");
- } else {
- if (mRssi != Integer.MAX_VALUE) {
- visibility.append(" rssi=");
- visibility.append(mRssi);
- if (mScanResult != null) {
- visibility.append(", f=");
- visibility.append(mScanResult.frequency);
+ } else if (result.frequency >= LOWER_FREQ_24GHZ
+ && result.frequency <= HIGHER_FREQ_24GHZ) {
+ if (result.level > rssi24) {
+ rssi24 = result.level;
+ }
+ if (n24 < 4) {
+ if (scans24GHz == null) scans24GHz = new StringBuilder();
+ scans24GHz.append(" \n{").append(result.BSSID);
+ if (bssid != null && result.BSSID.equals(bssid)) scans24GHz.append("*");
+ scans24GHz.append("=").append(result.frequency);
+ scans24GHz.append(",").append(result.level);
+ if (result.autoJoinStatus != 0) {
+ scans24GHz.append(",st=").append(result.autoJoinStatus);
+ }
+ if (result.numIpConfigFailures != 0) {
+ scans24GHz.append(",ipf=").append(result.numIpConfigFailures);
+ }
+ scans24GHz.append("}");
+ n24++;
}
}
}
+ visibility.append(" [");
+ if (num24 > 0) {
+ visibility.append("(").append(num24).append(")");
+ if (n24 <= 4) {
+ if (scans24GHz != null) {
+ visibility.append(scans24GHz.toString());
+ }
+ } else {
+ visibility.append("max=").append(rssi24);
+ if (scans24GHz != null) {
+ visibility.append(",").append(scans24GHz.toString());
+ }
+ }
+ }
+ visibility.append(";");
+ if (num5 > 0) {
+ visibility.append("(").append(num5).append(")");
+ if (n5 <= 4) {
+ if (scans5GHz != null) {
+ visibility.append(scans5GHz.toString());
+ }
+ } else {
+ visibility.append("max=").append(rssi5);
+ if (scans5GHz != null) {
+ visibility.append(",").append(scans5GHz.toString());
+ }
+ }
+ }
+ if (numBlackListed > 0)
+ visibility.append("!").append(numBlackListed);
+ visibility.append("]");
return visibility.toString();
}
@@ -589,7 +620,8 @@
}
public boolean isEphemeral() {
- return !isSaved() && mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
+ return mInfo != null && mInfo.isEphemeral() &&
+ mNetworkInfo != null && mNetworkInfo.getState() != State.DISCONNECTED;
}
/** Return whether the given {@link WifiInfo} is for this access point. */
@@ -635,28 +667,29 @@
ssid = config.providerFriendlyName;
else
ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
-
+
security = getSecurity(config);
networkId = config.networkId;
mConfig = config;
}
- private void loadResult(ScanResult result) {
+ private void initWithScanResult(ScanResult result) {
ssid = result.SSID;
security = getSecurity(result);
if (security == SECURITY_PSK)
pskType = getPskType(result);
mRssi = result.level;
- mScanResult = result;
- if (result.seen > mSeen) {
- mSeen = result.seen;
- }
+ mSeen = result.timestamp;
}
public void saveWifiState(Bundle savedState) {
- savedState.putParcelable(KEY_CONFIG, mConfig);
- savedState.putParcelable(KEY_SCANRESULT, mScanResult);
+ if (ssid != null) savedState.putString(KEY_SSID, getSsidStr());
+ savedState.putInt(KEY_SECURITY, security);
+ savedState.putInt(KEY_PSKTYPE, pskType);
+ if (mConfig != null) savedState.putParcelable(KEY_CONFIG, mConfig);
savedState.putParcelable(KEY_WIFIINFO, mInfo);
+ savedState.putParcelableArrayList(KEY_SCANRESULTCACHE,
+ new ArrayList<ScanResult>(mScanResultCache.snapshot().values()));
if (mNetworkInfo != null) {
savedState.putParcelable(KEY_NETWORKINFO, mNetworkInfo);
}
@@ -667,32 +700,31 @@
}
boolean update(ScanResult result) {
- if (result.seen > mSeen) {
- mSeen = result.seen;
- }
- if (WifiTracker.sVerboseLogging > 0) {
- if (mScanResultCache == null) {
- mScanResultCache = new LruCache<String, ScanResult>(32);
- }
- mScanResultCache.put(result.BSSID, result);
- }
-
if (ssid.equals(result.SSID) && security == getSecurity(result)) {
- if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) {
- int oldLevel = getLevel();
- mRssi = result.level;
- if (getLevel() != oldLevel && mAccessPointListener != null) {
- mAccessPointListener.onLevelChanged(this);
- }
+ /* Update the LRU timestamp, if BSSID exists */
+ mScanResultCache.get(result.BSSID);
+
+ /* Add or update the scan result for the BSSID */
+ mScanResultCache.put(result.BSSID, result);
+
+ int oldLevel = getLevel();
+ int oldRssi = getRssi();
+ mSeen = getSeen();
+ mRssi = (getRssi() + oldRssi)/2;
+ int newLevel = getLevel();
+
+ if (newLevel > 0 && newLevel != oldLevel && mAccessPointListener != null) {
+ mAccessPointListener.onLevelChanged(this);
}
// This flag only comes from scans, is not easily saved in config
if (security == SECURITY_PSK) {
pskType = getPskType(result);
}
- mScanResult = result;
+
if (mAccessPointListener != null) {
mAccessPointListener.onAccessPointChanged(this);
}
+
return true;
}
return false;
@@ -726,7 +758,7 @@
mAccessPointListener.onAccessPointChanged(this);
}
}
-
+
public static String getSummary(Context context, String ssid, DetailedState state,
boolean isEphemeral, String passpointProvider) {
if (state == DetailedState.CONNECTED && ssid == null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 19be4a5..ef08e19 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -28,6 +28,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.util.Log;
import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
@@ -35,9 +36,12 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -45,6 +49,7 @@
*/
public class WifiTracker {
private static final String TAG = "WifiTracker";
+ private static final boolean DBG = false;
/** verbose logging flag. this flag is set thru developer debugging options
* and used so as to assist with in-the-field WiFi connectivity debugging */
@@ -70,6 +75,10 @@
private boolean mSavedNetworksExist;
private boolean mRegistered;
private ArrayList<AccessPoint> mAccessPoints = new ArrayList<>();
+ private HashMap<String, Integer> mSeenBssids = new HashMap<>();
+ private HashMap<String, ScanResult> mScanResultCache = new HashMap<>();
+ private Integer mScanId = 0;
+ private static final int NUM_SCANS_TO_CONFIRM_AP_LOSS = 3;
private NetworkInfo mLastNetworkInfo;
private WifiInfo mLastInfo;
@@ -166,6 +175,11 @@
if (mScanner == null) {
mScanner = new Scanner();
}
+
+ mScanResultCache.clear();
+ mSeenBssids.clear();
+ mScanId = 0;
+
if (mWifiManager.isWifiEnabled()) {
mScanner.resume();
}
@@ -237,6 +251,33 @@
}
}
+ private Collection<ScanResult> fetchScanResults() {
+ mScanId++;
+ final List<ScanResult> newResults = mWifiManager.getScanResults();
+ for (ScanResult newResult : newResults) {
+ mScanResultCache.put(newResult.BSSID, newResult);
+ mSeenBssids.put(newResult.BSSID, mScanId);
+ }
+
+ if (mScanId > NUM_SCANS_TO_CONFIRM_AP_LOSS) {
+ if (DBG) Log.d(TAG, "------ Dumping SSIDs that were expired on this scan ------");
+ Integer threshold = mScanId - NUM_SCANS_TO_CONFIRM_AP_LOSS;
+ for (Iterator<Map.Entry<String, Integer>> it = mSeenBssids.entrySet().iterator();
+ it.hasNext(); /* nothing */) {
+ Map.Entry<String, Integer> e = it.next();
+ if (e.getValue() < threshold) {
+ ScanResult result = mScanResultCache.get(e.getKey());
+ if (DBG) Log.d(TAG, "Removing " + e.getKey() + ":(" + result.SSID + ")");
+ mScanResultCache.remove(e.getKey());
+ it.remove();
+ }
+ }
+ if (DBG) Log.d(TAG, "---- Done Dumping SSIDs that were expired on this scan ----");
+ }
+
+ return mScanResultCache.values();
+ }
+
private void updateAccessPoints() {
// Swap the current access points into a cached list.
List<AccessPoint> cachedAccessPoints = getAccessPoints();
@@ -283,7 +324,7 @@
}
}
- final List<ScanResult> results = mWifiManager.getScanResults();
+ final Collection<ScanResult> results = fetchScanResults();
if (results != null) {
for (ScanResult result : results) {
// Ignore hidden and ad-hoc networks.
@@ -305,7 +346,7 @@
accessPoint.update(mLastInfo, mLastNetworkInfo);
}
- if (result.passpointNetwork) {
+ if (result.isPasspointNetwork()) {
WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
if (config != null) {
accessPoint.update(config);
@@ -328,6 +369,24 @@
// Pre-sort accessPoints to speed preference insertion
Collections.sort(accessPoints);
+
+ // Log accesspoints that were deleted
+ if (DBG) Log.d(TAG, "------ Dumping SSIDs that were not seen on this scan ------");
+ for (AccessPoint prevAccessPoint : mAccessPoints) {
+ if (prevAccessPoint.getSsid() == null) continue;
+ String prevSsid = prevAccessPoint.getSsidStr();
+ boolean found = false;
+ for (AccessPoint newAccessPoint : accessPoints) {
+ if (newAccessPoint.getSsid() != null && newAccessPoint.getSsid().equals(prevSsid)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ if (DBG) Log.d(TAG, "Did not find " + prevSsid + " in this scan");
+ }
+ if (DBG) Log.d(TAG, "---- Done dumping SSIDs that were not seen on this scan ----");
+
mAccessPoints = accessPoints;
mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
}
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 469b776..71aefad 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -15,7 +15,6 @@
<provider android:name="SettingsProvider" android:authorities="settings"
android:multiprocess="false"
android:exported="true"
- android:writePermission="android.permission.WRITE_SETTINGS"
android:singleUser="true"
android:initOrder="100" />
</application>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 5137e1b..41043eb 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,18 @@
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.
+ if (!hasPermissionsToMutateSystemSettings()) {
+ return false;
+ }
// 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 +956,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 +1024,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 +1311,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 +1847,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 +1975,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/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 640fb29..9832b45 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -128,7 +128,7 @@
<activity
android:name=".BugreportWarningActivity"
- android:theme="@*android:style/Theme.Material.DayNight.Dialog.Alert"
+ android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
android:exported="false" />
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index 13747ed..6278650 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -27,6 +27,7 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.FileUtils;
@@ -77,21 +78,12 @@
@Override
public void onReceive(Context context, Intent intent) {
+ final Configuration conf = context.getResources().getConfiguration();
final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
final File screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
- // Files are kept on private storage, so turn into Uris that we can
- // grant temporary permissions for.
- final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile);
- final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile);
-
- boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt");
- if (!isPlainText) {
- // Already zipped, send it right away.
- sendBugreportNotification(context, bugreportFile, screenshotFile);
- } else {
- // Asynchronously zip the file first, then send it.
- sendZippedBugreportNotification(context, bugreportFile, screenshotFile);
+ if ((conf.uiMode & Configuration.UI_MODE_TYPE_MASK) != Configuration.UI_MODE_TYPE_WATCH) {
+ triggerLocalNotification(context, bugreportFile, screenshotFile);
}
// Clean up older bugreports in background
@@ -107,6 +99,29 @@
}.execute();
}
+ /**
+ * Responsible for triggering a notification that allows the user to start a
+ * "share" intent with the bug report. On watches we have other methods to allow the user to
+ * start this intent (usually by triggering it on another connected device); we don't need to
+ * display the notification in this case.
+ */
+ private void triggerLocalNotification(final Context context, final File bugreportFile,
+ final File screenshotFile) {
+ // Files are kept on private storage, so turn into Uris that we can
+ // grant temporary permissions for.
+ final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile);
+ final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile);
+
+ boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt");
+ if (!isPlainText) {
+ // Already zipped, send it right away.
+ sendBugreportNotification(context, bugreportFile, screenshotFile);
+ } else {
+ // Asynchronously zip the file first, then send it.
+ sendZippedBugreportNotification(context, bugreportFile, screenshotFile);
+ }
+ }
+
private static Intent buildWarningIntent(Context context, Intent sendIntent) {
final Intent intent = new Intent(context, BugreportWarningActivity.class);
intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
@@ -199,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/drawable/managed_profile_toast_background.xml b/packages/SystemUI/res/drawable/managed_profile_toast_background.xml
deleted file mode 100644
index 5c77b9a..0000000
--- a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <corners android:radius="2dp" />
- <solid android:color="@color/managed_profile_toast_background" />
-</shape>
diff --git a/packages/SystemUI/res/interpolator/assist_disclosure_trace.xml b/packages/SystemUI/res/interpolator/assist_disclosure_trace.xml
new file mode 100644
index 0000000..6b5cd37
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/assist_disclosure_trace.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.6"
+ android:controlY1="0"
+ android:controlX2="0.7"
+ android:controlY2="1"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 48af565..1488ad6 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -68,7 +68,6 @@
android:layout_height="@dimen/keyguard_affordance_height"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
- android:scaleType="center"
- android:contentDescription="@string/accessibility_unlock_button" />
+ android:scaleType="center" />
</com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/managed_profile_toast.xml b/packages/SystemUI/res/layout/managed_profile_toast.xml
deleted file mode 100644
index 5a01ca7..0000000
--- a/packages/SystemUI/res/layout/managed_profile_toast.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:background="@drawable/managed_profile_toast_background">
- <ImageView
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="16dp"
- android:src="@drawable/stat_sys_managed_profile_status"/>
- <TextView android:text="@string/managed_profile_foreground_toast"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@android:color/white"
- android:textSize="14sp"
- android:layout_gravity="center_horizontal" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 0ed1e2a..7617ed4 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -18,7 +18,7 @@
android:id="@+id/volume_dialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
+ android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
android:layout_marginLeft="@dimen/notification_side_padding"
android:layout_marginRight="@dimen/notification_side_padding"
android:background="@drawable/volume_dialog_background"
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index c6aa588..91e931d 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -17,6 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
+ android:id="@+id/volume_dialog_row"
android:paddingEnd="8dp"
android:paddingStart="8dp" >
@@ -49,6 +50,8 @@
android:layout_below="@id/volume_row_header"
android:layout_toEndOf="@id/volume_row_icon"
android:layout_toStartOf="@+id/volume_settings_button"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
android:paddingEnd="8dp"
android:paddingStart="8dp" />
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 55d4c16..0eb463f 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Ontsluit-knoppie, wag tans vir vingerafdruk"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontsluit sonder om jou vingerafdruk te gebruik"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af. Jy sal steeds foonoproepe kan maak."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..d909c44 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"የማስከፈቻ አዝራር፣ የጣት አሻራን በመጠበቅ ላይ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"የጣት አሻራዎን ሳይጠቀሙ ይክፈቱ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ክፈት"</string>
<string name="phone_label" msgid="2320074140205331708">"ስልክ ክፈት"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"የድምጽ ረዳትን ክፈት"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል። አሁንም የድምጽ ጥሪዎችን ማድረግ ይችላሉ።"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል።"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</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..6de6f4f 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -91,6 +91,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"زر إلغاء القفل، في انتظار بصمة إصبع"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"إلغاء القفل دون استخدام بصمة إصبعك"</string>
<string name="unlock_label" msgid="8779712358041029439">"إلغاء القفل"</string>
<string name="phone_label" msgid="2320074140205331708">"فتح الهاتف"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"فتح المساعد الصوتي"</string>
@@ -316,7 +318,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب. إلا أنه سيظل بإمكانك إجراء مكالمات هاتفية."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</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..81ac0ea 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kilid açma düyməsi, barmaq izi üçün gözləyir"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Barmaq izi istifadə etmədən kilidi açın"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır. Yenə də telefon zəngi edə bilərsiniz."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..49982f5 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Бутон за отключване – изчаква се отпечатък"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Отключете, без да използвате отпечатъка си"</string>
<string name="unlock_label" msgid="8779712358041029439">"отключване"</string>
<string name="phone_label" msgid="2320074140205331708">"отваряне на телефона"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отваряне на гласовата помощ"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри. Пак ще можете да извършвате телефонни обаждания."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</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..af5bd9b 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"আনলক বোতাম, আঙ্গুলের ছাপের জন্য প্রতীক্ষারত"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"আপনার আঙ্গুলের ছাপ ব্যবহার না করেই আনলক করুন"</string>
<string name="unlock_label" msgid="8779712358041029439">"আনলক করুন"</string>
<string name="phone_label" msgid="2320074140205331708">"ফোন খুলুন"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ভয়েস সহায়তা খুলুন"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷ আপনি এখনও ফোন কলগুলি করতে পারবেন৷"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</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..49b9a36 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botó de desbloqueig, esperant l\'empremta digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloqueja sense utilitzar l\'empremta digital"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Tot i això, encara podràs fer trucades."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..ccb7ea1 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tlačítko odemčení, čekání na otisk prstu"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odemknout bez otisku prstu"</string>
<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 +318,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..895da77d 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knap til oplåsning. Venter på fingeraftryk"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås op uden at bruge dit fingeraftryk"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil. Du vil stadig kunne foretage telefonopkald."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..1d0ea0a 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Schaltfläche \"Entsperren\", auf Fingerabdruck warten"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ohne Verwendung des Fingerabdrucks entsperren"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..3f28569 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Κουμπί ξεκλειδώματος, αναμονή για μοναδικό χαρακτηριστικό"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ξεκλείδωμα χωρίς τη χρήση του μοναδικού χαρακτηριστικού σας"</string>
<string name="unlock_label" msgid="8779712358041029439">"ξεκλείδωμα"</string>
<string name="phone_label" msgid="2320074140205331708">"άνοιγμα τηλεφώνου"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"άνοιγμα φωνητικής υποβοήθησης"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</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..88b5be0 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -87,6 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string>
<string name="unlock_label" msgid="8779712358041029439">"unlock"</string>
<string name="phone_label" msgid="2320074140205331708">"open phone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="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..88b5be0 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -87,6 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string>
<string name="unlock_label" msgid="8779712358041029439">"unlock"</string>
<string name="phone_label" msgid="2320074140205331708">"open phone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="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..88b5be0 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -87,6 +87,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string>
<string name="unlock_label" msgid="8779712358041029439">"unlock"</string>
<string name="phone_label" msgid="2320074140205331708">"open phone"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
<string name="notification_tap_again" msgid="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..4280191 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón Desbloquear, esperando la huella digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sin utilizar la huella digital"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluso los que provienen de alarmas, música, videos y juegos."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..28268ba 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo, esperando huella digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sin usar tu huella digital"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos). Seguirás pudiendo hacer llamadas de teléfono."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos)."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..0c35122 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Avamisnupp, sõrmejälje ootel"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ava sõrmejälge kasutamata"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja värinad. Saate siiski helistada."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja vibratsioonid."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..ebc609d 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Desblokeatzeko botoia; hatz-markaren zain"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desblokeatu hatz-markaren bidez"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak. Telefono-deiak egiteko aukera izaten jarraituko duzu."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..65d3866 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"دکمه باز کردن قفل، در انتظار اثر انگشت"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"باز کردن قفل بدون استفاده از اثر انگشت"</string>
<string name="unlock_label" msgid="8779712358041029439">"بازکردن قفل"</string>
<string name="phone_label" msgid="2320074140205331708">"باز کردن تلفن"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"«دستیار صوتی» را باز کنید"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند. همچنان میتوانید تماس تلفنی برقرار کنید."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</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..2f4f5a1 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Avauspainike, odotetaan sormenjälkeä."</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Avaa lukitus jollakin muulla tavalla kuin sormenjäljellä"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..a225864 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Bouton de déverrouillage. En attente d\'une empreinte digitale…"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..286aa32 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Bouton de déverrouillage. En attente d\'une empreinte digitale…"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez toujours passer des appels téléphoniques."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..ace93848 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo; agardando pola impresión dixital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquea sen usar a túa impresión dixital"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..f64a454 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"અનલૉક બટન, ફિંગરપ્રિન્ટ માટે રાહ જોઈ રહ્યાં છીએ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કર્યા વગર અનલૉક કરો"</string>
<string name="unlock_label" msgid="8779712358041029439">"અનલૉક કરો"</string>
<string name="phone_label" msgid="2320074140205331708">"ફોન ખોલો"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"વૉઇસ સહાય ખોલો"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે. તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને આ અવરોધિત કરે છે."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</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..ff441ab 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलॉक बटन, फ़िंगरप्रिंट की प्रतीक्षा कर रहा है"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"अपने फ़िंगरप्रिंट का उपयोग किए बिना अनलॉक करें"</string>
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करें"</string>
<string name="phone_label" msgid="2320074140205331708">"फ़ोन खोलें"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"वॉइस सहायक खोलें"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</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..5996979 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -88,6 +88,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Gumb za otključavanje, čekanje na otisak prsta"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključavanje bez otiska prsta"</string>
<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 +315,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre. I dalje ćete moći telefonirati."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..6cc4c51 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Feloldás gomb, várakozás az ujjlenyomatra"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Feloldás ujjlenyomat nélkül"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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 indíthat majd."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..e32c43e 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Ապակողպման կոճակ, մատնահետքի սպասում"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ապակողպել չօգտագործելով մատնահետքը"</string>
<string name="unlock_label" msgid="8779712358041029439">"ապակողպել"</string>
<string name="phone_label" msgid="2320074140205331708">"բացել հեռախոսը"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"բացեք ձայնային հուշումը"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռումները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայներն ու թրթռումները: Սակայն կկարողանաք կատարել հեռախոսազանգեր:"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռումները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայներն ու թրթռումները:"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</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..ebd7a43 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tombol buka kunci, menunggu sidik jari"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Buka kunci tanpa menggunakan sidik jari"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir. Anda tetap dapat melakukan panggilan telepon."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..ef40103 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Hnappur til að taka úr lás, beðið eftir fingrafari"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Taka úr lás án þess að nota fingrafar"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum. Þú getur áfram hringt símtöl."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..88b2cdb 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Pulsante Sblocca, in attesa dell\'impronta digitale"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Sblocca senza utilizzare l\'impronta digitale"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi. Potrai ancora telefonare."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..52da800 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"לחצן ביטול נעילה, ממתין לטביעת אצבע"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"בטל את הנעילה בלי להשתמש בטביעת האצבע"</string>
<string name="unlock_label" msgid="8779712358041029439">"בטל את הנעילה"</string>
<string name="phone_label" msgid="2320074140205331708">"פתח את הטלפון"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"פתח את המסייע הקולי"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"פעולה זו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. תוכל עדיין להתקשר."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"פעולה זו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"הודעות בדחיפות נמוכה יותר בהמשך"</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..01031d4 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ロック解除ボタン、指紋を待っています"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"指紋を使用せずにロック解除"</string>
<string name="unlock_label" msgid="8779712358041029439">"ロック解除"</string>
<string name="phone_label" msgid="2320074140205331708">"電話を起動"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"音声アシストを開く"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。電話をかけることはできます。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</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..9b94dd1 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"განბლოკვის ღილაკი, ელოდება თითის ანაბეჭდს"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"თქვენი თითის ანაბეჭდის გარეშე განბლოკვა"</string>
<string name="unlock_label" msgid="8779712358041029439">"განბლოკვა"</string>
<string name="phone_label" msgid="2320074140205331708">"ტელეფონის გახსნა"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ხმოვანი დახმარების გახსნა"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების. მიუხედავად ამისა, თქვენ მაინც შეძლებთ სატელეფონო ზარების განხორციელებას."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</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..9b20d87 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Құлыпты ашу түймесі, саусақ ізі күтілуде"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Саусақ ізін пайдаланбай құлыпты ашу"</string>
<string name="unlock_label" msgid="8779712358041029439">"бекітпесін ашу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонды ашу"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ашық дауыс көмекшісі"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі. Бірақ телефон қоңыраулары шалына береді."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</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..9a5bf06 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ប៊ូតុងដោះសោ កំពុងរង់ចាំស្នាមម្រាមដៃ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ដោះសោដោយមិនបាច់ប្រើស្នាមម្រាមដៃរបស់អ្នក"</string>
<string name="unlock_label" msgid="8779712358041029439">"ដោះសោ"</string>
<string name="phone_label" msgid="2320074140205331708">"បើកទូរស័ព្ទ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"បើកជំនួយសំឡេង"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ ដោយរួមបញ្ចូលទាំងសំឡេងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។ អ្នកនឹងនៅតែអាចធ្វើការហៅទូរស័ព្ទបានដដែល។"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ដែលចេញពីម៉ោងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</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..d706272 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ಅನ್ಲಾಕ್ ಬಟನ್, ಫಿಂಗರ್ಪ್ರಿಂಟ್ಗೆ ಕಾಯಲಾಗುತ್ತಿದೆ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ನಿಮ್ಮ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಬಳಸದೆಯೇ ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ಅನ್ಲಾಕ್ ಮಾಡು"</string>
<string name="phone_label" msgid="2320074140205331708">"ಫೋನ್ ತೆರೆಯಿರಿ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ಇದು ಅಲಾರಮ್ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಆಟಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. ನಿಮಗೆ ಈಗಲೂ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ಇದು ಅಲಾರಮ್ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಆಟಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</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..18018d9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"잠금 해제 버튼, 지문 파일 대기 중"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"지문 파일을 사용하지 않고 잠금 해제"</string>
<string name="unlock_label" msgid="8779712358041029439">"잠금 해제"</string>
<string name="phone_label" msgid="2320074140205331708">"휴대전화 열기"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"음성 지원 열기"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다. 전화는 걸 수 있습니다."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</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..38e9158 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -111,6 +111,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кулпуну ачуу баскычы, манжа изи күтүлүүдө"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Манжа изиңизди колдонбостон эле кулпуну ачыңыз"</string>
<string name="unlock_label" msgid="8779712358041029439">"кулпуну ачуу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонду ачуу"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"үн жардамчысысын ачуу"</string>
@@ -337,7 +339,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү сыяктуу нерселердин баары өчүрүлөт. Бирок телефон чала бересиз."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү сыяктуу нерселердин БААРЫ өчүрүлөт."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</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..ddf88d5 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ປົດລັອກປຸ່ມ, ກຳລັງລໍຖ້າລາຍນີ້ວມື"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ປົດລັອກໂດຍບໍ່ມີການໃຊ້ລາຍນີ້ວມືຂອງທ່ານ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ປົດລັອກ"</string>
<string name="phone_label" msgid="2320074140205331708">"ເປີດແປ້ນໂທລະສັບ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ຊ່ວເຫຼືອເປີດສຽງ"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ອັນນີ້ບລັອກທຸກສຽງ ແລະການສັ່ນ, ລວມທັງຈາກໂມງປຸກ, ເພງ, ວິດີໂອ, ແລະເກມ. ທ່ານຍັງຈະສາມາດໂທລະສັບໄດ້."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ອັນນີ້ບລັອກທຸກສຽງ ແລະການສັ່ນ, ລວມທັງຈາກໂມງປຸກ, ເພງ, ວິດີໂອ, ແລະເກມ."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</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..defdae2 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Atrakinimo mygtukas, laukiama kontrolinio kodo"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atrakinti nenaudojant kontrolinio kodo"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..8536dfb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -88,6 +88,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Atbloķēšanas poga; tiek gaidīts pirksta nospiedums"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atbloķēt, neizmantojot pirksta nospiedumu"</string>
<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 +315,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..b2d4a9f 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Копче за отклучување, се чека отпечаток"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Отклучете без да го користите вашиот отпечаток"</string>
<string name="unlock_label" msgid="8779712358041029439">"отклучи"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовна помош"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите. Сѐ уште ќе може да воспоставувате телефонски повици."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</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..68b8603 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"അൺലോക്ക് ബട്ടൺ, ഫിംഗർപ്രിന്റിനായി കാക്കുന്നു"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കാതെ അൺലോക്കുചെയ്യുക"</string>
<string name="unlock_label" msgid="8779712358041029439">"അൺലോക്കുചെയ്യുക"</string>
<string name="phone_label" msgid="2320074140205331708">"ഫോൺ തുറക്കുക"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"വോയ്സ് അസിസ്റ്റ് തുറക്കുക"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു. നിങ്ങൾക്ക് തുടർന്നും ഫോൺ വിളിക്കാനാകും."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</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..17e27a8 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -85,6 +85,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Toвчлуурыг онгойлгоно уу. Хурууны хээг хүлээж байна"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Хурууны хээ ашиглалгүйгээр түгжээг тайлаарай"</string>
<string name="unlock_label" msgid="8779712358041029439">"тайлах"</string>
<string name="phone_label" msgid="2320074140205331708">"утас нээх"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"дуут туслахыг нээнэ"</string>
@@ -310,7 +312,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог. Та дуудлага хийх боломжтой хэвээр байна."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</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..c331590 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलॉक बटण, फिंगरप्रिंटची प्रतीक्षा करीत आहे"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"आपले फिंगरप्रिंट न वापरता अनलॉक करा"</string>
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करा"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन उघडा"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"व्हॉइस सहाय्य उघडा"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते. आपण तरीही फोन कॉल करण्यात सक्षम व्हाल."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</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..435ed2c 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Butang buka kunci, menunggu cap jari"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Buka kunci tanpa menggunakan cap jari"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan. Anda masih boleh membuat panggilan telefon."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..7c60abe 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ခလုတ် ဖွင့်ရန်၊ လက်ဗွေရာအား စောင့်ပါ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"လက်ဗွေရာ မသုံးဘဲ ဖွင့်ပါ"</string>
<string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string>
<string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ဤအရာမှ နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား တားဆီးပေးသည်။ ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်နိုင်ဆဲဖြစ်မည်။"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား ဤအရာမှ တားဆီးပေး၏။"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</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..d8906c1 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Lås opp-knappen – venter på fingeravtrykk"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås opp uten å bruke fingeravtrykk"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill. Du kan fremdeles ringe."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..a83712a 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलक बटन, फिंगरप्रिन्ट पर्खँदै"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"तपाईँको फिंगरप्रिन्ट बिना नै अनलक गर्नुहोस्"</string>
<string name="unlock_label" msgid="8779712358041029439">"खोल्नुहोस्"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन खोल्नुहोस्"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"आवाज सहायता खोल्नुहोस्"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन रोक्छ। तपाईँ अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"यसले अलार्म, संगीत, भिडियोहरू र खेलहरूसहित सबै ध्वनिहरू र कम्पनहरूलाई रोक्छ।"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</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..0ca197f 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knop Ontgrendelen, wacht op vingerafdruk"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontgrendelen zonder uw vingerafdruk te gebruiken"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games. U kunt wel nog steeds bellen."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..6144a80 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ਅਨਲੌਕ ਬਟਨ, ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੇ ਬਿਨਾਂ ਅਨਲੌਕ ਕਰੋ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ਅਨਲੌਕ ਕਰੋ"</string>
<string name="phone_label" msgid="2320074140205331708">"ਫੋਨ ਖੋਲ੍ਹੋ"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"ਵੌਇਸ ਅਸਿਸਟ ਖੋਲ੍ਹੋ"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ।"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ।"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</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..1f35c85 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Przycisk odblokowania, oczekiwanie na odcisk palca"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odblokuj bez używania odcisku palca"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To zablokuje WSZYSTKIE dźwięki i wibracje, w tym alarmy, muzykę, filmy i gry. Nadal będzie można wykonywać połączenia."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"To zablokuje WSZYSTKIE dźwięki i wibracje – w tym alarmy, muzykę, filmy i gry."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..e2ec2ff 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botão de desbloqueio, a aguardar a impressão digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sem utilizar a sua impressão digital"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos. Continua a ser possível telefonar."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..c3fcd27 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botão de desbloqueio. Aguardando impressão digital"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sem usar impressão digital"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos. Você ainda poderá fazer chamadas telefônicas."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..91c2df2 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -88,6 +88,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Buton pentru deblocare, se așteaptă amprenta"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Deblocați fără amprentă"</string>
<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 +315,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..f1428ea 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка разблокировки, отсканируйте отпечаток пальца"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Разблокировать без отпечатка пальца"</string>
<string name="unlock_label" msgid="8779712358041029439">"Разблокировать."</string>
<string name="phone_label" msgid="2320074140205331708">"Открыть телефон."</string>
<string name="voice_assist_label" msgid="3956854378310019854">"включить аудиоподсказки"</string>
@@ -316,7 +318,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео). При этом вы сможете разговаривать по телефону."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео)."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные оповещения"</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..a2ba414 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"අගුළු ඇරීමේ බොත්තම, ඇඟිලි සලකුණු සඳහා රැඳී සිටිමින්"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ඔබේ ඇඟිලි සලකුණ භාවිත නොකර අගුළු අරින්න"</string>
<string name="unlock_label" msgid="8779712358041029439">"අඟුල අරින්න"</string>
<string name="phone_label" msgid="2320074140205331708">"දුරකථනය විවෘත කරන්න"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"විවෘත හඬ සහාය"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"මෙය සීනු, සංගීතය, වීඩියෝ, සහ ක්රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි. ඔබට තවමත් දුරකථන ඇමතුම් සිදු කිරීමේ හැකියාව ඇත."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"මෙය සීනු, සංගීතය, වීඩියෝ, සහ ක්රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"හදිසිය අඩු දැනුම් දීම් පහත"</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..65e0cd5 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tlačidlo Odomknúť, čaká sa na odtlačok"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odomknúť bez použitia odtlačku"</string>
<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 +318,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier. Stále však budete môcť telefonovať."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..8e80c38 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Gumb za odklepanje, čakanje na prstni odtis"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odklepanje brez prstnega odtisa"</string>
<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 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger. Še vedno boste lahko opravljali telefonske klice."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..2498706 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Butoni i shkyçjes, në pritje për gjurmën e gishtit"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Shkyçe pa përdorur gjurmën e gishtit"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..d82922c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -88,6 +88,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Дугме за откључавање, чека се на отисак прста"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Откључај без коришћења отиска прста"</string>
<string name="unlock_label" msgid="8779712358041029439">"откључај"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовну помоћ"</string>
@@ -313,7 +315,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</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..6271966 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Upplåsningsknapp – väntar på fingeravtryck"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås upp utan att använda fingeravtryck"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel. Du kan fortfarande ringa."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..f78f433 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kitufe cha kufungua, kinasubiri kitambulisho"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Fungua bila kutumia kitambulisho chako"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa na pamoja na ile inayotokana na kengele, muziki, video na michezo. Bado utaweza kupiga simu."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa ni pamoja na ile inayotokana na kengele, muziki, video na michezo."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>+"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..227c4e8 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"திறப்பதற்கான பொத்தான், கைரேகைக்காகக் காத்திருக்கிறது"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கவும்"</string>
<string name="unlock_label" msgid="8779712358041029439">"திற"</string>
<string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</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..308e243 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"అన్లాక్ బటన్, వేలిముద్ర కోసం వేచి ఉంది"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"మీ వేలిముద్రను ఉపయోగించకుండా అన్లాక్ చేయండి"</string>
<string name="unlock_label" msgid="8779712358041029439">"అన్లాక్ చేయి"</string>
<string name="phone_label" msgid="2320074140205331708">"ఫోన్ను తెరువు"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ సహాయకం తెరువు"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్లను బ్లాక్ చేస్తుంది. మీరు ఇప్పటికీ ఫోన్ కాల్లు చేయగలుగుతారు."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్లను బ్లాక్ చేస్తుంది."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్లు దిగువన"</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..8a5e216 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ปุ่มปลดล็อก กำลังรอลายนิ้วมือ"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ปลดล็อกโดยไม่ต้องใช้ลายนิ้วมือ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ปลดล็อก"</string>
<string name="phone_label" msgid="2320074140205331708">"เปิดโทรศัพท์"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"เปิดตัวช่วยเสียง"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม คุณจะยังโทรออกได้อยู่"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</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..0d0ee09 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"I-unlock ang button, naghihintay para sa fingerprint"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"I-unlock nang hindi ginagamit ang iyong fingerprint"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro. Magagawa mo pa ring tumawag."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..8f7b5f7 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kilit açma düğmesi, parmak izi bekleniyor"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Kilidi, parmak iziniz olmadan açın"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir. Telefon aramaları yapmaya devam edebileceksiniz."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..9ed4397 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -89,6 +89,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка розблокування. Очікується цифровий відбиток"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Розблокувати без цифрового відбитка"</string>
<string name="unlock_label" msgid="8779712358041029439">"розблокувати"</string>
<string name="phone_label" msgid="2320074140205331708">"відкрити телефон"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"запустити голосові підказки"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри. Ви зможете телефонувати."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</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..d132933 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"بٹن غیر مقفل کریں، فنگر پرنٹ کا منتظر"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"فنگر پرنٹ استعمال کیے بغیرغیر مقفل کریں"</string>
<string name="unlock_label" msgid="8779712358041029439">"غیر مقفل کریں"</string>
<string name="phone_label" msgid="2320074140205331708">"فون کھولیں"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"صوتی معاون کھولیں"</string>
@@ -312,7 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔ آپ ابھی بھی فون کالز کر سکیں گے۔"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</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..a971aaf 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Qulfdan chiqarish tugmasi, barmoq izi kutilmoqda"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Barmoq izisiz qulfdan chiqarish"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu BARCHA, jumladan signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi. Siz telefon qo‘ng‘iroqlarini bemalol amalga oshirishingiz mumkin."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu BARCHA, jumladan, signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..ea4da80 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Nút Mở khóa, đang chờ vân tay"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Mở khóa không dùng vân tay của bạn"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"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>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"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."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"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..618cf09 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解锁按钮,请用指纹解锁"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指纹解锁"</string>
<string name="unlock_label" msgid="8779712358041029439">"解锁"</string>
<string name="phone_label" msgid="2320074140205331708">"打开电话"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"打开语音助理"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。您仍然可以拨打电话。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</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..a9a4f26 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解鎖按鈕,正在等待指紋解鎖"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指紋解鎖"</string>
<string name="unlock_label" msgid="8779712358041029439">"解鎖"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"開啟語音助手"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲,但您仍可撥打電話。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</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..19c4e64 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解鎖按鈕,正在等待指紋"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指紋進行解鎖"</string>
<string name="unlock_label" msgid="8779712358041029439">"解除鎖定"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"開啟語音小幫手"</string>
@@ -314,7 +316,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。您仍可以撥打電話。"</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</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..0de3267 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -87,6 +87,8 @@
<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>
+ <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Inkinobho yokuvula, ilinde izigxivizo zeminwe"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Vula ngaphandle kokusebenzisa izigxivizo zakho zeminwe"</string>
<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 +314,8 @@
<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>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Lokhu kuvimbela YONKE imisindo nokudludliza, kufaka phakathi ama-alamu, umculo, amavidiyo, namageyimu. Usazokwazi ukwenza amkholi wefoni."</string>
+ <string name="zen_silence_introduction" msgid="3137882381093271568">"Lokhu kuvimbela YONKE imisindo nokudlidliza, kufaka phakathi kusuka kuma-alamu, umculo, amavidiyo, namageyimu."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Thinta futhi ukuze uvule"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 9a96939..0dcbe88 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -143,6 +143,4 @@
<color name="volume_icon_color">#ffffffff</color>
<color name="volume_settings_icon_color">#7fffffff</color>
<color name="volume_slider_inactive">#FFB0BEC5</color><!-- blue grey 200 -->
-
- <color name="managed_profile_toast_background">#E5000000</color><!-- 90% black -->
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b0e71f9..155f5ea 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -575,4 +575,16 @@
<!-- Standard image button size for volume dialog buttons -->
<dimen name="volume_button_size">48dp</dimen>
+
+ <!-- Volume dialog root view bottom margin, at rest -->
+ <dimen name="volume_dialog_margin_bottom">4dp</dimen>
+
+ <!-- Padding between icon and text for managed profile toast -->
+ <dimen name="managed_profile_toast_padding">4dp</dimen>
+
+ <!-- Thickness of the assist disclosure beams -->
+ <dimen name="assist_disclosure_thickness">3dp</dimen>
+
+ <!-- Thickness of the shadows of the assist disclosure beams -->
+ <dimen name="assist_disclosure_shadow_thickness">1.5dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 47c642d..d32ce55 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -215,6 +215,10 @@
<string name="accessibility_voice_assist_button">Voice Assist</string>
<!-- Content description of the unlock button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_unlock_button">Unlock</string>
+ <!-- Content description of the unlock button when fingerpint is on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_unlock_button_fingerprint">Unlock button, waiting for fingerprint</string>
+ <!-- Accessibility action of the unlock button when fingerpint is on (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_unlock_without_fingerprint">Unlock without using your fingerprint</string>
<!-- Click action label for accessibility for the unlock button. [CHAR LIMIT=NONE] -->
<string name="unlock_label">unlock</string>
<!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] -->
@@ -751,8 +755,11 @@
<!-- Zen mode: Priority only customization button label -->
<string name="zen_priority_customize_button">Customize</string>
- <!-- Zen mode: Total silence introduction message on first use -->
- <string name="zen_silence_introduction">This blocks ALL sounds and vibrations, including from alarms, music, videos, and games. You’ll still be able to make phone calls.</string>
+ <!-- Zen mode: Total silence introduction message on first use (voice capable devices) -->
+ <string name="zen_silence_introduction_voice">This blocks ALL sounds and vibrations, including from alarms, music, videos, and games. You’ll still be able to make phone calls.</string>
+
+ <!-- Zen mode: Total silence introduction message on first use (non-voice capable devices) -->
+ <string name="zen_silence_introduction">This blocks ALL sounds and vibrations, including from alarms, music, videos, and games.</string>
<!-- Text for overflow card on Keyguard when there is not enough space for all notifications on Keyguard. [CHAR LIMIT=1] -->
<string name="keyguard_more_overflow_text">+<xliff:g id="number_of_notifications" example="5">%d</xliff:g></string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 67d3312..1889862 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -291,11 +291,6 @@
<item name="android:textColor">#ffb0b3c5</item>
</style>
- <style name="VolumeDialogAnimations">
- <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
- <item name="android:windowExitAnimation">@android:anim/fade_out</item>
- </style>
-
<style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
<item name="android:background">@drawable/btn_borderless_rect</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 29d2a01..3657cf2 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -44,6 +44,7 @@
})
public @interface Key {
String SEARCH_APP_WIDGET_ID = "searchAppWidgetId";
+ String SEARCH_APP_WIDGET_PACKAGE = "searchAppWidgetPackage";
String DEBUG_MODE_ENABLED = "debugModeEnabled";
String HOTSPOT_TILE_LAST_USED = "HotspotTileLastUsed";
String COLOR_INVERSION_TILE_LAST_USED = "ColorInversionTileLastUsed";
@@ -80,6 +81,14 @@
get(context).edit().putLong(key, value).apply();
}
+ public static String getString(Context context, @Key String key, String defaultValue) {
+ return get(context).getString(key, defaultValue);
+ }
+
+ public static void putString(Context context, @Key String key, String value) {
+ get(context).edit().putString(key, value).apply();
+ }
+
public static Map<String, ?> getAll(Context context) {
return get(context).getAll();
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
new file mode 100644
index 0000000..c3a8f2e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -0,0 +1,263 @@
+/*
+ * 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.systemui.assist;
+
+import com.android.systemui.R;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Handler;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.AnimationUtils;
+
+/**
+ * Visually discloses that contextual data was provided to an assistant.
+ */
+public class AssistDisclosure {
+ private final Context mContext;
+ private final WindowManager mWm;
+ private final Handler mHandler;
+
+ private AssistDisclosureView mView;
+ private boolean mViewAdded;
+
+ public AssistDisclosure(Context context, Handler handler) {
+ mContext = context;
+ mHandler = handler;
+ mWm = mContext.getSystemService(WindowManager.class);
+ }
+
+ public void postShow() {
+ mHandler.removeCallbacks(mShowRunnable);
+ mHandler.post(mShowRunnable);
+ }
+
+ private void show() {
+ if (mView == null) {
+ mView = new AssistDisclosureView(mContext);
+ }
+ if (!mViewAdded) {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
+ PixelFormat.TRANSLUCENT);
+ lp.setTitle("AssistDisclosure");
+
+ mWm.addView(mView, lp);
+ mViewAdded = true;
+ }
+ }
+
+ private void hide() {
+ if (mViewAdded) {
+ mWm.removeView(mView);
+ mViewAdded = false;
+ }
+ }
+
+ private Runnable mShowRunnable = new Runnable() {
+ @Override
+ public void run() {
+ show();
+ }
+ };
+
+ private class AssistDisclosureView extends View
+ implements ValueAnimator.AnimatorUpdateListener {
+
+ public static final int TRACING_ANIMATION_DURATION = 600;
+ public static final int ALPHA_IN_ANIMATION_DURATION = 450;
+ public static final int ALPHA_OUT_ANIMATION_DURATION = 400;
+
+ private float mThickness;
+ private float mShadowThickness;
+ private final Paint mPaint = new Paint();
+ private final Paint mShadowPaint = new Paint();
+
+ private final ValueAnimator mTracingAnimator;
+ private final ValueAnimator mAlphaOutAnimator;
+ private final ValueAnimator mAlphaInAnimator;
+ private final AnimatorSet mAnimator;
+
+ private float mTracingProgress = 0;
+ private int mAlpha = 0;
+
+ public AssistDisclosureView(Context context) {
+ super(context);
+
+ mTracingAnimator = ValueAnimator.ofFloat(0, 1).setDuration(TRACING_ANIMATION_DURATION);
+ mTracingAnimator.addUpdateListener(this);
+ mTracingAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ R.interpolator.assist_disclosure_trace));
+ mAlphaInAnimator = ValueAnimator.ofInt(0, 255).setDuration(ALPHA_IN_ANIMATION_DURATION);
+ mAlphaInAnimator.addUpdateListener(this);
+ mAlphaInAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_slow_in));
+ mAlphaOutAnimator = ValueAnimator.ofInt(255, 0).setDuration(
+ ALPHA_OUT_ANIMATION_DURATION);
+ mAlphaOutAnimator.addUpdateListener(this);
+ mAlphaOutAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_linear_in));
+ mAnimator = new AnimatorSet();
+ mAnimator.play(mAlphaInAnimator).with(mTracingAnimator);
+ mAnimator.play(mAlphaInAnimator).before(mAlphaOutAnimator);
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ boolean mCancelled;
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mCancelled = false;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCancelled) {
+ hide();
+ }
+ }
+ });
+
+ PorterDuffXfermode srcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
+ mPaint.setColor(Color.WHITE);
+ mPaint.setXfermode(srcMode);
+ mShadowPaint.setColor(Color.DKGRAY);
+ mShadowPaint.setXfermode(srcMode);
+
+ mThickness = getResources().getDimension(R.dimen.assist_disclosure_thickness);
+ mShadowThickness = getResources().getDimension(
+ R.dimen.assist_disclosure_shadow_thickness);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ startAnimation();
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ mAnimator.cancel();
+
+ mTracingProgress = 0;
+ mAlpha = 0;
+ }
+
+ private void startAnimation() {
+ mAnimator.cancel();
+ mAnimator.start();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mPaint.setAlpha(mAlpha);
+ mShadowPaint.setAlpha(mAlpha / 4);
+
+ drawGeometry(canvas, mShadowPaint, mShadowThickness);
+ drawGeometry(canvas, mPaint, 0);
+ }
+
+ private void drawGeometry(Canvas canvas, Paint paint, float padding) {
+ final int width = getWidth();
+ final int height = getHeight();
+ float thickness = mThickness;
+ final float pixelProgress = mTracingProgress * (width + height - 2 * thickness);
+
+ float bottomProgress = Math.min(pixelProgress, width / 2f);
+ if (bottomProgress > 0) {
+ drawBeam(canvas,
+ width / 2f - bottomProgress,
+ height - thickness,
+ width / 2f + bottomProgress,
+ height, paint, padding);
+ }
+
+ float sideProgress = Math.min(pixelProgress - bottomProgress, height - thickness);
+ if (sideProgress > 0) {
+ drawBeam(canvas,
+ 0,
+ (height - thickness) - sideProgress,
+ thickness,
+ height - thickness, paint, padding);
+ drawBeam(canvas,
+ width - thickness,
+ (height - thickness) - sideProgress,
+ width,
+ height - thickness, paint, padding);
+ }
+
+ float topProgress = Math.min(pixelProgress - bottomProgress - sideProgress,
+ width / 2 - thickness);
+ if (sideProgress > 0 && topProgress > 0) {
+ drawBeam(canvas,
+ thickness,
+ 0,
+ thickness + topProgress,
+ thickness, paint, padding);
+ drawBeam(canvas,
+ (width - thickness) - topProgress,
+ 0,
+ width - thickness,
+ thickness, paint, padding);
+ }
+ }
+
+ private void drawBeam(Canvas canvas, float left, float top, float right, float bottom,
+ Paint paint, float padding) {
+ canvas.drawRect(left - padding,
+ top - padding,
+ right + padding,
+ bottom + padding,
+ paint);
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (animation == mAlphaOutAnimator) {
+ mAlpha = (int) mAlphaOutAnimator.getAnimatedValue();
+ } else if (animation == mAlphaInAnimator) {
+ mAlpha = (int) mAlphaInAnimator.getAnimatedValue();
+ } else if (animation == mTracingAnimator) {
+ mTracingProgress = (float) mTracingAnimator.getAnimatedValue();
+ }
+ invalidate();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 445ecb6..6ba5626 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -55,6 +55,8 @@
private final Context mContext;
private final WindowManager mWindowManager;
+ private final AssistDisclosure mAssistDisclosure;
+
private AssistOrbContainer mView;
private final PhoneStatusBar mBar;
private final AssistUtils mAssistUtils;
@@ -100,6 +102,7 @@
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT), false,
mAssistSettingsObserver);
mAssistSettingsObserver.onChange(false);
+ mAssistDisclosure = new AssistDisclosure(context, new Handler());
}
public void onConfigurationChanged() {
@@ -122,14 +125,11 @@
}
}
- public void onGestureInvoked(boolean vibrate) {
+ public void onGestureInvoked() {
if (mAssistComponent == null) {
return;
}
- if (vibrate) {
- vibrate();
- }
final boolean isService = isAssistantService();
if (isService || !isVoiceSessionRunning()) {
showOrb();
@@ -187,8 +187,11 @@
mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL |
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL);
+ boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
+
final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, structureEnabled, UserHandle.USER_CURRENT);
if (intent == null) {
return;
}
@@ -196,6 +199,10 @@
intent.setComponent(mAssistComponent);
}
+ if (structureEnabled) {
+ showDisclosure();
+ }
+
try {
final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.search_launch_enter, R.anim.search_launch_exit);
@@ -280,10 +287,6 @@
v.setImageDrawable(null);
}
- private void vibrate() {
- mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
- }
-
private boolean isAssistantService() {
return mAssistComponent == null ?
false : mAssistComponent.equals(getVoiceInteractorComponentName());
@@ -297,4 +300,16 @@
pw.println("AssistManager state:");
pw.print(" mAssistComponent="); pw.println(mAssistComponent);
}
+
+ public void showDisclosure() {
+ mAssistDisclosure.postShow();
+ }
+
+ public void onUserSwitched(int newUserId) {
+ updateAssistInfo();
+ }
+
+ public void prepareBeforeInvocation() {
+ updateAssistInfo();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c06b34f..7f61fc1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -62,6 +62,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardDisplayManager;
+import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
@@ -526,6 +527,17 @@
public boolean isScreenOn() {
return mDeviceInteractive;
}
+
+ @Override
+ public int getBouncerPromptReason() {
+ int currentUser = ActivityManager.getCurrentUser();
+ if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
+ || mUpdateMonitor.isUnlockWithFingerPrintPossible(currentUser))
+ && !mTrustManager.hasUserAuthenticatedSinceBoot(currentUser)) {
+ return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ }
+ return KeyguardSecurityView.PROMPT_REASON_NONE;
+ }
};
public void userActivity() {
@@ -610,9 +622,8 @@
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
- mUpdateMonitor.registerCallback(mUpdateCallback);
-
doKeyguardLocked(null);
+ mUpdateMonitor.registerCallback(mUpdateCallback);
}
// Most services aren't available until the system reaches the ready state, so we
// send it here when the device first boots.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 9761cd1..4b1453d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -390,7 +390,7 @@
mDetailSettingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mHost.startSettingsActivity(settingsIntent);
+ mHost.startActivityDismissingKeyguard(settingsIntent);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 72bb136..38fade2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -306,7 +306,7 @@
}
public interface Host {
- void startSettingsActivity(Intent intent);
+ void startActivityDismissingKeyguard(Intent intent);
void warn(String message, Throwable t);
void collapsePanels();
Looper getLooper();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index a9e8b38..07406b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -82,7 +82,7 @@
if (mDataController.isMobileDataSupported()) {
showDetail(true);
} else {
- mHost.startSettingsActivity(CELLULAR_SETTINGS);
+ mHost.startActivityDismissingKeyguard(CELLULAR_SETTINGS);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index f97f519..359ed5f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -28,6 +28,7 @@
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Prefs;
@@ -98,6 +99,14 @@
@Override
public void handleClick() {
+ if (mController.isVolumeRestricted()) {
+ // Collapse the panels, so the user can see the toast.
+ mHost.collapsePanels();
+ Toast.makeText(mContext, mContext.getString(
+ com.android.internal.R.string.error_message_change_not_allowed),
+ Toast.LENGTH_LONG).show();
+ return;
+ }
mDisable.setAllowAnimation(true);
mDisableTotalSilence.setAllowAnimation(true);
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
@@ -263,7 +272,7 @@
private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
@Override
public void onPrioritySettings() {
- mHost.startSettingsActivity(ZEN_PRIORITY_SETTINGS);
+ mHost.startActivityDismissingKeyguard(ZEN_PRIORITY_SETTINGS);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 19f4df6..f7f7acb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -96,7 +96,11 @@
private void sendIntent(String type, PendingIntent pi, String uri) {
try {
if (pi != null) {
- pi.send();
+ if (pi.isActivity()) {
+ getHost().startActivityDismissingKeyguard(pi.getIntent());
+ } else {
+ pi.send();
+ }
} else if (uri != null) {
final Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 9bc5b75..c33ef7c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -104,7 +104,7 @@
@Override
protected void handleSecondaryClick() {
if (!mWifiController.canConfigWifi()) {
- mHost.startSettingsActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+ mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_WIFI_SETTINGS));
return;
}
if (!mState.enabled) {
@@ -290,7 +290,7 @@
@Override
public void onSettingsActivityTriggered(Intent settingsIntent) {
- mHost.startSettingsActivity(settingsIntent);
+ mHost.startActivityDismissingKeyguard(settingsIntent);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 89c456c..6a45369 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -20,7 +20,6 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ITaskStackListener;
-import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -37,11 +36,10 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.MutableBoolean;
-import android.util.Pair;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
-
+import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SystemUI;
@@ -170,6 +168,7 @@
Handler mHandler;
TaskStackListenerImpl mTaskStackListener;
RecentsOwnerEventProxyReceiver mProxyBroadcastReceiver;
+ RecentsAppWidgetHost mAppWidgetHost;
boolean mBootCompleted;
boolean mStartAnimationTriggered;
boolean mCanReuseTaskStackViews = true;
@@ -235,6 +234,7 @@
mSystemServicesProxy = new SystemServicesProxy(mContext);
mHandler = new Handler();
mTaskStackBounds = new Rect();
+ mAppWidgetHost = new RecentsAppWidgetHost(mContext, Constants.Values.App.AppWidgetHostId);
// Register the task stack listener
mTaskStackListener = new TaskStackListenerImpl(mHandler);
@@ -255,7 +255,7 @@
// Initialize some static datastructures
TaskStackViewLayoutAlgorithm.initializeCurve();
// Load the header bar layout
- reloadHeaderBarLayout(true);
+ reloadHeaderBarLayout();
// When we start, preload the data associated with the previous recent tasks.
// We can use a new plan since the caches will be the same.
@@ -488,11 +488,11 @@
// Don't reuse task stack views if the configuration changes
mCanReuseTaskStackViews = false;
// Reload the header bar layout
- reloadHeaderBarLayout(false);
+ reloadHeaderBarLayout();
}
/** Prepares the header bar layout. */
- void reloadHeaderBarLayout(boolean reloadWidget) {
+ void reloadHeaderBarLayout() {
Resources res = mContext.getResources();
mWindowRect = mSystemServicesProxy.getWindowRect();
mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
@@ -500,12 +500,16 @@
mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
mConfig.updateOnConfigurationChange();
- if (reloadWidget) {
- // Reload the widget id before we get the task stack bounds
- reloadSearchBarAppWidget(mContext, mSystemServicesProxy);
+ Rect searchBarBounds = new Rect();
+ // Try and pre-emptively bind the search widget on startup to ensure that we
+ // have the right thumbnail bounds to animate to.
+ // Note: We have to reload the widget id before we get the task stack bounds below
+ if (mSystemServicesProxy.getOrBindSearchAppWidget(mContext, mAppWidgetHost) != null) {
+ mConfig.getSearchBarBounds(mWindowRect.width(), mWindowRect.height(),
+ mStatusBarHeight, searchBarBounds);
}
mConfig.getAvailableTaskStackBounds(mWindowRect.width(), mWindowRect.height(),
- mStatusBarHeight, (mConfig.hasTransposedNavBar ? mNavBarWidth : 0),
+ mStatusBarHeight, (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), searchBarBounds,
mTaskStackBounds);
if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0);
@@ -532,24 +536,6 @@
}
}
- /** Prepares the search bar app widget */
- void reloadSearchBarAppWidget(Context context, SystemServicesProxy ssp) {
- // Try and pre-emptively bind the search widget on startup to ensure that we
- // have the right thumbnail bounds to animate to.
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- // If there is no id, then bind a new search app widget
- if (mConfig.searchBarAppWidgetId < 0) {
- AppWidgetHost host = new RecentsAppWidgetHost(context,
- Constants.Values.App.AppWidgetHostId);
- Pair<Integer, AppWidgetProviderInfo> widgetInfo = ssp.bindSearchAppWidget(host);
- if (widgetInfo != null) {
- // Save the app widget id into the settings
- mConfig.updateSearchBarAppWidgetId(context, widgetInfo.first);
- }
- }
- }
- }
-
/** Toggles the recents activity */
void toggleRecentsActivity() {
// If the user has toggled it too quickly, then just eat up the event here (it's better than
@@ -799,27 +785,13 @@
// If there is no thumbnail transition, but is launching from home into recents, then
// use a quick home transition and do the animation from home
if (hasRecentTasks) {
- // Get the home activity info
String homeActivityPackage = mSystemServicesProxy.getHomeActivityPackageName();
- // Get the search widget info
- AppWidgetProviderInfo searchWidget = null;
- String searchWidgetPackage = null;
- if (mConfig.hasSearchBarAppWidget()) {
- searchWidget = mSystemServicesProxy.getAppWidgetInfo(
- mConfig.searchBarAppWidgetId);
- } else {
- searchWidget = mSystemServicesProxy.resolveSearchAppWidget();
- }
- if (searchWidget != null && searchWidget.provider != null) {
- searchWidgetPackage = searchWidget.provider.getPackageName();
- }
- // Determine whether we are coming from a search owned home activity
- boolean fromSearchHome = false;
- if (homeActivityPackage != null && searchWidgetPackage != null &&
- homeActivityPackage.equals(searchWidgetPackage)) {
- fromSearchHome = true;
- }
+ String searchWidgetPackage =
+ Prefs.getString(mContext, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE, null);
+ // Determine whether we are coming from a search owned home activity
+ boolean fromSearchHome = (homeActivityPackage != null) &&
+ homeActivityPackage.equals(searchWidgetPackage);
ActivityOptions opts = getHomeTransitionActivityOptions(fromSearchHome);
startAlternateRecentsActivity(topTask, opts, true /* fromHome */, fromSearchHome,
false /* fromThumbnail */, stackVr);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 3cd769e..bf15c68 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -28,7 +28,6 @@
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewStub;
@@ -36,6 +35,7 @@
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -49,7 +49,6 @@
import com.android.systemui.recents.views.ViewAnimation;
import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
/**
@@ -74,9 +73,9 @@
RecentsResizeTaskDialog mResizeTaskDebugDialog;
// Search AppWidget
- AppWidgetProviderInfo mSearchAppWidgetInfo;
+ AppWidgetProviderInfo mSearchWidgetInfo;
RecentsAppWidgetHost mAppWidgetHost;
- RecentsAppWidgetHostView mSearchAppWidgetHostView;
+ RecentsAppWidgetHostView mSearchWidgetHostView;
// Runnables to finish the Recents activity
FinishRecentsRunnable mFinishLaunchHomeRunnable;
@@ -108,10 +107,15 @@
public void run() {
// Finish Recents
if (mLaunchIntent != null) {
- if (mLaunchOpts != null) {
- startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT);
- } else {
- startActivityAsUser(mLaunchIntent, UserHandle.CURRENT);
+ try {
+ if (mLaunchOpts != null) {
+ startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT);
+ } else {
+ startActivityAsUser(mLaunchIntent, UserHandle.CURRENT);
+ }
+ } catch (Exception e) {
+ Console.logError(RecentsActivity.this,
+ getString(R.string.recents_launch_error_message, "Home"));
}
} else {
finish();
@@ -162,8 +166,10 @@
// When the screen turns off, dismiss Recents to Home
dismissRecentsToHome(false);
} else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
- // When the search activity changes, update the Search widget
- refreshSearchWidget();
+ // When the search activity changes, update the search widget view
+ SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
+ mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(context, mAppWidgetHost);
+ refreshSearchWidgetView();
}
}
};
@@ -247,7 +253,7 @@
if (mRecentsView.hasValidSearchBar()) {
mRecentsView.setSearchBarVisibility(View.VISIBLE);
} else {
- addSearchBarAppWidgetView();
+ refreshSearchWidgetView();
}
}
@@ -255,60 +261,6 @@
mScrimViews.prepareEnterRecentsAnimation();
}
- /** Attempts to allocate and bind the search bar app widget */
- void bindSearchBarAppWidget() {
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
-
- // Reset the host view and widget info
- mSearchAppWidgetHostView = null;
- mSearchAppWidgetInfo = null;
-
- // Try and load the app widget id from the settings
- int appWidgetId = mConfig.searchBarAppWidgetId;
- if (appWidgetId >= 0) {
- mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId);
- if (mSearchAppWidgetInfo == null) {
- // If there is no actual widget associated with that id, then delete it and
- // prepare to bind another app widget in its place
- ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId);
- appWidgetId = -1;
- }
- }
-
- // If there is no id, then bind a new search app widget
- if (appWidgetId < 0) {
- Pair<Integer, AppWidgetProviderInfo> widgetInfo =
- ssp.bindSearchAppWidget(mAppWidgetHost);
- if (widgetInfo != null) {
- // Save the app widget id into the settings
- mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first);
- mSearchAppWidgetInfo = widgetInfo.second;
- }
- }
- }
- }
-
- /** Creates the search bar app widget view */
- void addSearchBarAppWidgetView() {
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- int appWidgetId = mConfig.searchBarAppWidgetId;
- if (appWidgetId >= 0) {
- mSearchAppWidgetHostView = (RecentsAppWidgetHostView) mAppWidgetHost.createView(
- this, appWidgetId, mSearchAppWidgetInfo);
- Bundle opts = new Bundle();
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
- AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
- mSearchAppWidgetHostView.updateAppWidgetOptions(opts);
- // Set the padding to 0 for this search widget
- mSearchAppWidgetHostView.setPadding(0, 0, 0, 0);
- mRecentsView.setSearchBar(mSearchAppWidgetHostView);
- } else {
- mRecentsView.setSearchBar(null);
- }
- }
- }
-
/** Dismisses recents if we are already visible and the intent is to toggle the recents view */
boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) {
SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
@@ -387,7 +339,7 @@
inflateDebugOverlay();
// Bind the search app widget when we first start up
- bindSearchBarAppWidget();
+ mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(this, mAppWidgetHost);
// Register the broadcast receiver to handle messages when the screen is turned off
IntentFilter filter = new IntentFilter();
@@ -492,7 +444,8 @@
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
mRecentsView.startEnterRecentsAnimation(ctx);
- if (mConfig.searchBarAppWidgetId >= 0) {
+
+ if (mSearchWidgetInfo != null) {
final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> cbRef =
new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(
RecentsActivity.this);
@@ -648,9 +601,22 @@
/**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
@Override
- public void refreshSearchWidget() {
- bindSearchBarAppWidget();
- addSearchBarAppWidgetView();
+ public void refreshSearchWidgetView() {
+ if (mSearchWidgetInfo != null) {
+ SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
+ int searchWidgetId = ssp.getSearchAppWidgetId(this);
+ mSearchWidgetHostView = (RecentsAppWidgetHostView) mAppWidgetHost.createView(
+ this, searchWidgetId, mSearchWidgetInfo);
+ Bundle opts = new Bundle();
+ opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+ AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
+ mSearchWidgetHostView.updateAppWidgetOptions(opts);
+ // Set the padding to 0 for this search widget
+ mSearchWidgetHostView.setPadding(0, 0, 0, 0);
+ mRecentsView.setSearchBar(mSearchWidgetHostView);
+ } else {
+ mRecentsView.setSearchBar(null);
+ }
}
/**** DebugOverlayView.DebugOverlayViewCallbacks ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
index d4e50f8..0102332 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
@@ -20,26 +20,20 @@
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.model.RecentsTaskLoader;
/** Our special app widget host for the Search widget */
public class RecentsAppWidgetHost extends AppWidgetHost {
/* Callbacks to notify when an app package changes */
interface RecentsAppWidgetHostCallbacks {
- public void refreshSearchWidget();
+ void refreshSearchWidgetView();
}
- Context mContext;
RecentsAppWidgetHostCallbacks mCb;
- RecentsConfiguration mConfig;
boolean mIsListening;
public RecentsAppWidgetHost(Context context, int hostId) {
super(context, hostId);
- mContext = context;
- mConfig = RecentsConfiguration.getInstance();
}
public void startListening(RecentsAppWidgetHostCallbacks cb) {
@@ -57,7 +51,6 @@
}
// Ensure that we release any references to the callbacks
mCb = null;
- mContext = null;
mIsListening = false;
}
@@ -67,18 +60,14 @@
return new RecentsAppWidgetHostView(context);
}
+ /**
+ * Note: this is only called for packages that have updated, not removed.
+ */
@Override
protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
- if (mCb == null) return;
- if (mContext == null) return;
-
- SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
- if (appWidgetId > -1 && appWidgetId == mConfig.searchBarAppWidgetId) {
- // The search provider may have changed, so just delete the old widget and bind it again
- ssp.unbindSearchAppWidget(this, appWidgetId);
- // Update the search widget
- mConfig.updateSearchBarAppWidgetId(mContext, -1);
- mCb.refreshSearchWidget();
+ super.onProviderChanged(appWidgetId, appWidgetInfo);
+ if (mIsListening && mCb != null) {
+ mCb.refreshSearchWidgetView();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java
index 1ed755a..672d602 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java
@@ -18,6 +18,7 @@
import android.appwidget.AppWidgetHostView;
import android.content.Context;
+import android.view.View;
import android.widget.RemoteViews;
public class RecentsAppWidgetHostView extends AppWidgetHostView {
@@ -37,6 +38,14 @@
super.updateAppWidget(remoteViews);
}
+ @Override
+ protected View getErrorView() {
+ // Just return an empty view as the error view when failing to inflate the Recents search
+ // bar widget (this is mainly to catch the case where we try and inflate the widget view
+ // while the search provider is updating)
+ return new View(mContext);
+ }
+
/**
* Updates the last orientation that this widget was inflated.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 244fada..dfe7e96 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -73,7 +73,6 @@
public int maxNumTasksToLoad;
/** Search bar */
- int searchBarAppWidgetId = -1;
public int searchBarSpaceHeightPx;
/** Task stack */
@@ -207,8 +206,6 @@
// Search Bar
searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);
- searchBarAppWidgetId = Prefs.getInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID,
- -1 /* defaultValue */);
// Task stack
taskStackScrollDuration =
@@ -279,12 +276,6 @@
systemInsets.set(insets);
}
- /** Updates the search bar app widget */
- public void updateSearchBarAppWidgetId(Context context, int appWidgetId) {
- searchBarAppWidgetId = appWidgetId;
- Prefs.putInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, appWidgetId);
- }
-
/** Updates the states that need to be re-read whenever we re-initialize. */
void updateOnReinitialize(Context context, SystemServicesProxy ssp) {
// Check if the developer options are enabled
@@ -304,11 +295,6 @@
launchedHasConfigurationChanged = true;
}
- /** Returns whether the search bar app widget exists. */
- public boolean hasSearchBarAppWidget() {
- return searchBarAppWidgetId >= 0;
- }
-
/** Returns whether the status bar scrim should be animated when shown for the first time. */
public boolean shouldAnimateStatusBarScrim() {
return launchedFromHome;
@@ -335,9 +321,7 @@
* the system insets.
*/
public void getAvailableTaskStackBounds(int windowWidth, int windowHeight, int topInset,
- int rightInset, Rect taskStackBounds) {
- Rect searchBarBounds = new Rect();
- getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds);
+ int rightInset, Rect searchBarBounds, Rect taskStackBounds) {
if (isLandscape && hasTransposedSearchBar) {
// In landscape, the search bar appears on the left, but we overlay it on top
taskStackBounds.set(0, topInset, windowWidth - rightInset, windowHeight);
@@ -355,10 +339,6 @@
Rect searchBarSpaceBounds) {
// Return empty rects if search is not enabled
int searchBarSize = searchBarSpaceHeightPx;
- if (!Constants.DebugFlags.App.EnableSearchLayout || !hasSearchBarAppWidget()) {
- searchBarSize = 0;
- }
-
if (isLandscape && hasTransposedSearchBar) {
// In landscape, the search bar appears on the left
searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 272d39a..b60c66f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -62,9 +62,11 @@
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsAppWidgetHost;
import java.io.IOException;
import java.util.ArrayList;
@@ -527,14 +529,57 @@
}
/**
- * Resolves and returns the first Recents widget from the same package as the global
- * assist activity.
+ * Returns the current search widget id.
*/
- public AppWidgetProviderInfo resolveSearchAppWidget() {
- if (mAwm == null) return null;
- if (mAssistComponent == null) return null;
+ public int getSearchAppWidgetId(Context context) {
+ return Prefs.getInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, -1);
+ }
- // Find the first Recents widget from the same package as the global assist activity
+ /**
+ * Returns the current search widget info, binding a new one if necessary.
+ */
+ public AppWidgetProviderInfo getOrBindSearchAppWidget(Context context, AppWidgetHost host) {
+ int searchWidgetId = Prefs.getInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, -1);
+ AppWidgetProviderInfo searchWidgetInfo = mAwm.getAppWidgetInfo(searchWidgetId);
+ AppWidgetProviderInfo resolvedSearchWidgetInfo = resolveSearchAppWidget();
+
+ // Return the search widget info if it hasn't changed
+ if (searchWidgetInfo != null && resolvedSearchWidgetInfo != null &&
+ searchWidgetInfo.provider.equals(resolvedSearchWidgetInfo.provider)) {
+ if (Prefs.getString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE, null) == null) {
+ Prefs.putString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE,
+ searchWidgetInfo.provider.getPackageName());
+ }
+ return searchWidgetInfo;
+ }
+
+ // Delete the old widget
+ if (searchWidgetId != -1) {
+ host.deleteAppWidgetId(searchWidgetId);
+ }
+
+ // And rebind a new search widget
+ if (resolvedSearchWidgetInfo != null) {
+ Pair<Integer, AppWidgetProviderInfo> widgetInfo = bindSearchAppWidget(host,
+ resolvedSearchWidgetInfo);
+ if (widgetInfo != null) {
+ Prefs.putInt(context, Prefs.Key.SEARCH_APP_WIDGET_ID, widgetInfo.first);
+ Prefs.putString(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE,
+ widgetInfo.second.provider.getPackageName());
+ return widgetInfo.second;
+ }
+ }
+
+ // If we fall through here, then there is no resolved search widget, so clear the state
+ Prefs.remove(context, Prefs.Key.SEARCH_APP_WIDGET_ID);
+ Prefs.remove(context, Prefs.Key.SEARCH_APP_WIDGET_PACKAGE);
+ return null;
+ }
+
+ /**
+ * Returns the first Recents widget from the same package as the global assist activity.
+ */
+ private AppWidgetProviderInfo resolveSearchAppWidget() {
List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders(
AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
for (AppWidgetProviderInfo info : widgets) {
@@ -548,45 +593,21 @@
/**
* Resolves and binds the search app widget that is to appear in the recents.
*/
- public Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host) {
+ private Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host,
+ AppWidgetProviderInfo resolvedSearchWidgetInfo) {
if (mAwm == null) return null;
if (mAssistComponent == null) return null;
- // Find the first Recents widget from the same package as the global assist activity
- AppWidgetProviderInfo searchWidgetInfo = resolveSearchAppWidget();
-
- // Return early if there is no search widget
- if (searchWidgetInfo == null) return null;
-
// Allocate a new widget id and try and bind the app widget (if that fails, then just skip)
int searchWidgetId = host.allocateAppWidgetId();
Bundle opts = new Bundle();
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
- if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, searchWidgetInfo.provider, opts)) {
+ if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, resolvedSearchWidgetInfo.provider, opts)) {
host.deleteAppWidgetId(searchWidgetId);
return null;
}
- return new Pair<Integer, AppWidgetProviderInfo>(searchWidgetId, searchWidgetInfo);
- }
-
- /**
- * Returns the app widget info for the specified app widget id.
- */
- public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
- if (mAwm == null) return null;
-
- return mAwm.getAppWidgetInfo(appWidgetId);
- }
-
- /**
- * Destroys the specified app widget.
- */
- public void unbindSearchAppWidget(AppWidgetHost host, int appWidgetId) {
- if (mAwm == null) return;
-
- // Delete the app widget
- host.deleteAppWidgetId(appWidgetId);
+ return new Pair<>(searchWidgetId, resolvedSearchWidgetInfo);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index fa97a86e..6cb11b1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -287,17 +287,14 @@
/** Adds the search bar */
public void setSearchBar(RecentsAppWidgetHostView searchBar) {
- // Create the search bar (and hide it if we have no recent tasks)
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- // Remove the previous search bar if one exists
- if (mSearchBar != null && indexOfChild(mSearchBar) > -1) {
- removeView(mSearchBar);
- }
- // Add the new search bar
- if (searchBar != null) {
- mSearchBar = searchBar;
- addView(mSearchBar);
- }
+ // Remove the previous search bar if one exists
+ if (mSearchBar != null && indexOfChild(mSearchBar) > -1) {
+ removeView(mSearchBar);
+ }
+ // Add the new search bar
+ if (searchBar != null) {
+ mSearchBar = searchBar;
+ addView(mSearchBar);
}
}
@@ -324,8 +321,8 @@
int height = MeasureSpec.getSize(heightMeasureSpec);
// Get the search bar bounds and measure the search bar layout
+ Rect searchBarSpaceBounds = new Rect();
if (mSearchBar != null) {
- Rect searchBarSpaceBounds = new Rect();
mConfig.getSearchBarBounds(width, height, mConfig.systemInsets.top, searchBarSpaceBounds);
mSearchBar.measure(
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.width(), MeasureSpec.EXACTLY),
@@ -334,7 +331,7 @@
Rect taskStackBounds = new Rect();
mConfig.getAvailableTaskStackBounds(width, height, mConfig.systemInsets.top,
- mConfig.systemInsets.right, taskStackBounds);
+ mConfig.systemInsets.right, searchBarSpaceBounds, taskStackBounds);
// Measure each TaskStackView with the full width and height of the window since the
// transition view is a child of that stack view
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 a496548..3e66907 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -303,6 +303,7 @@
try {
ActivityManagerNative.getDefault()
.keyguardWaitingForActivityDrawn();
+ ActivityManagerNative.getDefault().resumeAppSwitches();
} catch (RemoteException e) {
}
}
@@ -315,7 +316,9 @@
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
true /* force */);
visibilityChanged(false);
+ mAssistManager.hideAssist();
}
+
// Wait for activity start.
return handled;
}
@@ -393,13 +396,16 @@
if (recentTask != null && recentTask.size() > 0) {
UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId);
if (user != null && user.isManagedProfile()) {
- LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View layout = inflater.inflate(R.layout.managed_profile_toast, null);
- Toast toast = new Toast(mContext);
- toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
- toast.setDuration(Toast.LENGTH_SHORT);
- toast.setView(layout);
+ Toast toast = Toast.makeText(mContext,
+ R.string.managed_profile_foreground_toast,
+ Toast.LENGTH_SHORT);
+ TextView text = (TextView) toast.getView().findViewById(
+ android.R.id.message);
+ text.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ R.drawable.stat_sys_managed_profile_status, 0, 0, 0);
+ int paddingPx = mContext.getResources().getDimensionPixelSize(
+ R.dimen.managed_profile_toast_padding);
+ text.setCompoundDrawablePadding(paddingPx);
toast.show();
}
}
@@ -1610,18 +1616,13 @@
/**
* 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 =
- (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
+ boolean clearNotificationEffects = !isPanelFullyCollapsed() &&
+ (mShowLockscreenNotifications ||
+ (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED));
mBarService.onPanelRevealed(clearNotificationEffects);
} else {
mBarService.onPanelHidden();
@@ -1632,6 +1633,19 @@
}
/**
+ * Clear Buzz/Beep/Blink.
+ */
+ public void clearNotificationEffects() {
+ try {
+ mBarService.clearNotificationEffects();
+ } catch (RemoteException e) {
+ // Won't fail unless the world has ended.
+ }
+ }
+
+ protected abstract boolean isPanelFullyCollapsed();
+
+ /**
* Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
* about the failure.
*
@@ -2098,4 +2112,11 @@
}
return mStatusBarKeyguardViewManager.isSecure();
}
+
+ @Override
+ public void showAssistDisclosure() {
+ if (mAssistManager != null) {
+ mAssistManager.showDisclosure();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 80fdd28..0deff08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -61,6 +61,7 @@
private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT;
private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT;
private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT;
+ private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -104,6 +105,7 @@
public void appTransitionPending();
public void appTransitionCancelled();
public void appTransitionStarting(long startTime, long duration);
+ public void showAssistDisclosure();
}
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -274,6 +276,13 @@
}
}
+ public void showAssistDisclosure() {
+ synchronized (mList) {
+ mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
+ mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
+ }
+ }
+
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
@@ -366,6 +375,9 @@
Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
mCallbacks.appTransitionStarting(data.first, data.second);
break;
+ case MSG_ASSIST_DISCLOSURE:
+ mCallbacks.showAssistDisclosure();
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 5a4acb4..da1f03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -224,7 +224,10 @@
public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
String description, boolean isWide, int subId) {
- PhoneState state = getOrInflateState(subId);
+ PhoneState state = getState(subId);
+ if (state == null) {
+ return;
+ }
state.mMobileVisible = statusIcon.visible && !mBlockMobile;
state.mMobileStrengthId = statusIcon.icon;
state.mMobileTypeId = statusType;
@@ -281,13 +284,14 @@
return true;
}
- private PhoneState getOrInflateState(int subId) {
+ private PhoneState getState(int subId) {
for (PhoneState state : mPhoneStates) {
if (state.mSubId == subId) {
return state;
}
}
- return inflatePhoneState(subId);
+ Log.e(TAG, "Unexpected subscription " + subId);
+ return null;
}
private PhoneState inflatePhoneState(int subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 10c35af..df8c7fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -114,6 +114,7 @@
/ mPanel.getMaxPanelHeight());
mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight
+ mNotificationsTopPadding);
+ mPanel.clearNotificattonEffects();
mHeadsUpManager.unpinAll();
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 3258a9f..815e123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -614,6 +614,13 @@
}
};
+ private final Runnable mHideTransientIndicationRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mIndicationController.hideTransientIndication();
+ }
+ };
+
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -657,6 +664,10 @@
@Override
public void onFingerprintError(int msgId, String errString) {
// TODO: Go to bouncer if this is "too many attempts" (lockout) error.
+ mIndicationController.showTransientIndication(errString,
+ getResources().getColor(R.color.system_warning_color, null));
+ removeCallbacks(mHideTransientIndicationRunnable);
+ postDelayed(mHideTransientIndicationRunnable, 5000);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 3737d05..a7afec4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -26,6 +26,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.R;
import com.android.keyguard.ViewMediatorCallback;
@@ -46,6 +47,7 @@
private ViewGroup mRoot;
private boolean mShowingSoon;
private Choreographer mChoreographer = Choreographer.getInstance();
+ private int mBouncerPromptReason;
public KeyguardBouncer(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager,
@@ -68,6 +70,8 @@
return;
}
+ mBouncerPromptReason = mCallback.getBouncerPromptReason();
+
// Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole
// Keyguard. If we need to authenticate, show the bouncer.
if (!mKeyguardView.dismiss()) {
@@ -84,12 +88,24 @@
public void run() {
mRoot.setVisibility(View.VISIBLE);
mKeyguardView.onResume();
+ showPromptReason(mBouncerPromptReason);
mKeyguardView.startAppearAnimation();
mShowingSoon = false;
mKeyguardView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
};
+ /**
+ * Show a string explaining why the security view needs to be solved.
+ *
+ * @param reason a flag indicating which string should be shown, see
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE}
+ * and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}
+ */
+ public void showPromptReason(int reason) {
+ mKeyguardView.showPromptReason(reason);
+ }
+
private void cancelShowRunnable() {
mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mShowRunnable, null);
mShowingSoon = false;
@@ -184,6 +200,7 @@
* notifications on Keyguard, like SIM PIN/PUK.
*/
public boolean needsFullscreenBouncer() {
+ ensureView();
if (mKeyguardView != null) {
SecurityMode mode = mKeyguardView.getSecurityMode();
return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 2063b26..6bcb766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -16,14 +16,13 @@
package com.android.systemui.statusbar.phone;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.Context;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
@@ -54,6 +53,7 @@
private final TrustDrawable mTrustDrawable;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
+ private boolean mHasFingerPrintIcon;
public LockIcon(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -128,6 +128,11 @@
setRestingAlpha(
anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
setImageDrawable(icon);
+ String contentDescription = getResources().getString(anyFingerprintIcon
+ ? R.string.accessibility_unlock_button_fingerprint
+ : R.string.accessibility_unlock_button);
+ setContentDescription(contentDescription);
+ mHasFingerPrintIcon = anyFingerprintIcon;
if (animation != null) {
// If we play the draw on animation, delay it by one frame when the screen is
@@ -167,6 +172,20 @@
setFocusable(mAccessibilityController.isAccessibilityEnabled());
}
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ if (mHasFingerPrintIcon) {
+ // Avoid that the button description is also spoken
+ info.setClassName(LockIcon.class.getName());
+ AccessibilityNodeInfo.AccessibilityAction unlock
+ = new AccessibilityNodeInfo.AccessibilityAction(
+ AccessibilityNodeInfo.ACTION_CLICK,
+ getContext().getString(R.string.accessibility_unlock_without_fingerprint));
+ info.addAction(unlock);
+ }
+ }
+
public void setAccessibilityController(AccessibilityController accessibilityController) {
mAccessibilityController = accessibilityController;
}
@@ -194,7 +213,8 @@
return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
} else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
- } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN) {
+ } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
+ && !mUnlockMethodCache.isCurrentlyInsecure()) {
return R.drawable.lockscreen_fingerprint_draw_off_animation;
} else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
return R.drawable.lockscreen_fingerprint_draw_on_animation;
@@ -206,14 +226,14 @@
private int getState() {
boolean fingerprintRunning =
KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
- if (mTransientFpError) {
+ if (mUnlockMethodCache.isCurrentlyInsecure()) {
+ return STATE_LOCK_OPEN;
+ } else if (mTransientFpError) {
return STATE_FINGERPRINT_ERROR;
} else if (fingerprintRunning) {
return STATE_FINGERPRINT;
} else if (mUnlockMethodCache.isFaceUnlockRunning()) {
return STATE_FACE_UNLOCK;
- } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
- return STATE_LOCK_OPEN;
} else {
return STATE_LOCKED;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c30cb34..cf0d670 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2340,4 +2340,8 @@
public void setPanelScrimMinFraction(float minFraction) {
mBar.panelScrimMinFractionChanged(minFraction);
}
+
+ public void clearNotificattonEffects() {
+ mStatusBar.clearNotificationEffects();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index cf553ec..e1a400d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -28,6 +28,8 @@
public abstract class PanelBar extends FrameLayout {
public static final boolean DEBUG = false;
public static final String TAG = PanelBar.class.getSimpleName();
+ private static final boolean SPEW = false;
+
public static final void LOG(String fmt, Object... args) {
if (!DEBUG) return;
Log.v(TAG, String.format(fmt, args));
@@ -167,7 +169,7 @@
public void panelExpansionChanged(PanelView panel, float frac, boolean expanded) {
boolean fullyClosed = true;
PanelView fullyOpenedPanel = null;
- if (DEBUG) LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
+ if (SPEW) LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
mPanelExpandedFractionSum = 0f;
for (PanelView pv : mPanels) {
pv.setVisibility(expanded ? View.VISIBLE : View.INVISIBLE);
@@ -180,7 +182,7 @@
fullyClosed = false;
final float thisFrac = pv.getExpandedFraction();
mPanelExpandedFractionSum += thisFrac;
- if (DEBUG) LOG("panelExpansionChanged: -> %s: f=%.1f", pv.getName(), thisFrac);
+ if (SPEW) LOG("panelExpansionChanged: -> %s: f=%.1f", pv.getName(), thisFrac);
if (panel == pv) {
if (thisFrac == 1f) fullyOpenedPanel = panel;
}
@@ -195,7 +197,7 @@
onAllPanelsCollapsed();
}
- if (DEBUG) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
+ if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
(fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
}
@@ -241,7 +243,7 @@
}
public void onExpandingFinished() {
-
+ if (DEBUG) LOG("onExpandingFinished");
}
public void onClosingFinished() {
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 cd90d27..3678cf1 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;
@@ -105,6 +106,7 @@
import com.android.systemui.EventLogTags;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
@@ -457,7 +459,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 +474,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 +499,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 +524,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) {
@@ -614,7 +634,7 @@
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
- mStatusBarWindow.mService = this;
+ mStatusBarWindow.setService(this);
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -657,8 +677,6 @@
mNotificationPanelDebugText.setVisibility(View.VISIBLE);
}
- updateShowSearchHoldoff();
-
try {
boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
@@ -994,11 +1012,6 @@
return mStatusBarWindow;
}
- public void invokeAssistGesture(boolean vibrate) {
- mHandler.removeCallbacks(mInvokeAssist);
- mAssistManager.onGestureInvoked(vibrate);
- }
-
public int getStatusBarHeight() {
if (mNaturalBarHeight < 0) {
final Resources res = mContext.getResources();
@@ -1025,30 +1038,28 @@
}
};
- private int mShowSearchHoldoff = 0;
- private Runnable mInvokeAssist = new Runnable() {
- public void run() {
- invokeAssistGesture(true /* vibrate */);
+ private final View.OnLongClickListener mLongPressHomeListener
+ = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (shouldDisableNavbarGestures()) {
+ return false;
+ }
+ mAssistManager.prepareBeforeInvocation();
+ mAssistManager.onGestureInvoked();
awakenDreams();
if (mNavigationBarView != null) {
mNavigationBarView.abortCurrentGesture();
}
+ return true;
}
};
- View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
+ private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (!shouldDisableNavbarGestures()) {
- mHandler.removeCallbacks(mInvokeAssist);
- mHandler.postDelayed(mInvokeAssist, mShowSearchHoldoff);
- }
- break;
-
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mHandler.removeCallbacks(mInvokeAssist);
awakenDreams();
break;
}
@@ -1076,6 +1087,7 @@
mNavigationBarView.getBackButton().setLongClickable(true);
mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
+ mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
mAssistManager.onConfigurationChanged();
}
@@ -1216,10 +1228,6 @@
}
}
- private void updateShowSearchHoldoff() {
- mShowSearchHoldoff = ViewConfiguration.getLongPressTimeout();
- }
-
private void updateNotificationShade() {
if (mStackScroller == null) return;
@@ -2902,7 +2910,6 @@
updateResources();
repositionNavigationBar();
- updateShowSearchHoldoff();
updateRowStates();
mIconController.updateResources();
mScreenPinningRequest.onConfigurationChanged();
@@ -2917,12 +2924,16 @@
updateNotifications();
resetUserSetupObserver();
setControllerUsers();
+ mAssistManager.onUserSwitched(newUserId);
}
private void setControllerUsers() {
if (mZenModeController != null) {
mZenModeController.setUserId(mCurrentUserId);
}
+ if (mSecurityController != null) {
+ mSecurityController.onUserSwitched(mCurrentUserId);
+ }
}
private void resetUserSetupObserver() {
@@ -2987,9 +2998,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 +3018,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
@@ -3101,16 +3121,16 @@
|| (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
}
- public void postStartSettingsActivity(final Intent intent, int delay) {
+ public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- handleStartSettingsActivity(intent, true /*onlyProvisioned*/);
+ handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
}
}, delay);
}
- private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
+ private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
}
@@ -3260,6 +3280,11 @@
return mState;
}
+ @Override
+ protected boolean isPanelFullyCollapsed() {
+ return mNotificationPanel.isFullyCollapsed();
+ }
+
public void showKeyguard() {
if (mLaunchTransitionFadingAway) {
mNotificationPanel.animate().cancel();
@@ -3886,6 +3911,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/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 25a93dd..12434ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -129,8 +129,8 @@
}
@Override
- public void startSettingsActivity(final Intent intent) {
- mStatusBar.postStartSettingsActivity(intent, 0);
+ public void startActivityDismissingKeyguard(final Intent intent) {
+ mStatusBar.postStartActivityDismissingKeyguard(intent, 0);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index c3719d4..bacf890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -137,6 +137,12 @@
scheduleUpdate();
}
+ public void abortKeyguardFadingOut() {
+ if (mAnimateKeyguardFadingOut) {
+ endAnimateKeyguardFadingOut();
+ }
+ }
+
public void animateGoingToFullShade(long delay, long duration) {
mDurationOverride = duration;
mAnimationDelay = delay;
@@ -321,17 +327,21 @@
mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
mUpdatePending = false;
updateScrims();
- mAnimateKeyguardFadingOut = false;
mDurationOverride = -1;
mAnimationDelay = 0;
// Make sure that we always call the listener even if we didn't start an animation.
+ endAnimateKeyguardFadingOut();
+ mAnimationStarted = false;
+ return true;
+ }
+
+ private void endAnimateKeyguardFadingOut() {
+ mAnimateKeyguardFadingOut = false;
if (!mAnimationStarted && mOnAnimationFinished != null) {
mOnAnimationFinished.run();
mOnAnimationFinished = null;
}
- mAnimationStarted = false;
- return true;
}
public void setBackDropView(BackDropView backDropView) {
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..a69416a 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) {
@@ -99,6 +100,7 @@
public void show(Bundle options) {
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true);
+ mScrimController.abortKeyguardFadingOut();
reset();
}
@@ -163,6 +165,7 @@
public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
mScreenOn = true;
+ mScreenWillWakeUp = false;
mPhoneStatusBar.onScreenTurnedOn();
if (callback != null) {
callbackAfterDraw(callback);
@@ -182,6 +185,10 @@
});
}
+ public void notifyScreenWakeUpRequested() {
+ mScreenWillWakeUp = !mScreenOn;
+ }
+
public void verifyUnlock() {
dismiss();
}
@@ -297,7 +304,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/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 634270c..0e22aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -53,7 +53,7 @@
private int mRightInset = 0;
- PhoneStatusBar mService;
+ private PhoneStatusBar mService;
private final Paint mTransparentSrcPaint = new Paint();
public StatusBarWindowView(Context context, AttributeSet attrs) {
@@ -124,14 +124,22 @@
}
@Override
- protected void onAttachedToWindow () {
- super.onAttachedToWindow();
-
+ protected void onFinishInflate() {
+ super.onFinishInflate();
mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
R.id.notification_stack_scroller);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
- mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
mBrightnessMirror = findViewById(R.id.brightness_mirror);
+ }
+
+ public void setService(PhoneStatusBar service) {
+ mService = service;
+ mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
+ }
+
+ @Override
+ protected void onAttachedToWindow () {
+ super.onAttachedToWindow();
// We really need to be able to animate while window animations are going on
// so that activities may be started asynchronously from panel animations
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 3cc9297..daa84ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -154,6 +154,12 @@
}
private void updateConnected() {
+ // Make sure our connection state is up to date.
+ int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState();
+ if (state != mConnectionState) {
+ mConnectionState = state;
+ mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
+ }
if (mLastDevice != null && mLastDevice.isConnected()) {
// Our current device is still valid.
return;
@@ -203,9 +209,9 @@
@Override
public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
- mConnectionState = state;
mLastDevice = cachedDevice;
updateConnected();
+ mConnectionState = state;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 6bc51fa..4c99792 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -57,7 +57,7 @@
if (isLongClickable()) {
// Just an old-fashioned ImageView
performLongClick();
- } else {
+ } else if (mSupportsLongpress) {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
}
@@ -92,7 +92,7 @@
super.onInitializeAccessibilityNodeInfo(info);
if (mCode != 0) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
- if (mSupportsLongpress) {
+ if (mSupportsLongpress || isLongClickable()) {
info.addAction(
new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
}
@@ -115,7 +115,7 @@
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
playSoundEffect(SoundEffectConstants.CLICK);
return true;
- } else if (action == ACTION_LONG_CLICK && mCode != 0 && mSupportsLongpress) {
+ } else if (action == ACTION_LONG_CLICK && mCode != 0) {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendEvent(KeyEvent.ACTION_UP, 0);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
@@ -144,10 +144,8 @@
// Provide the same haptic feedback that the system offers for virtual keys.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
- }
+ removeCallbacks(mCheckLongPress);
+ postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
break;
case MotionEvent.ACTION_MOVE:
x = (int)ev.getX();
@@ -162,9 +160,7 @@
if (mCode != 0) {
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
+ removeCallbacks(mCheckLongPress);
break;
case MotionEvent.ACTION_UP:
final boolean doIt = isPressed();
@@ -183,9 +179,7 @@
performClick();
}
}
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
+ removeCallbacks(mCheckLongPress);
break;
}
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..b1c650e 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
@@ -290,6 +291,7 @@
notifyListenersIfNecessary();
} else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
updateDataSim();
+ notifyListenersIfNecessary();
}
}
@@ -307,7 +309,6 @@
// for long.
mCurrentState.dataSim = true;
}
- notifyListenersIfNecessary();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 1ba87da..ff0e8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -110,6 +110,8 @@
// The current user ID.
private int mCurrentUserId;
+ private OnSubscriptionsChangedListener mSubscriptionListener;
+
// Handler that all broadcasts are received on.
private final Handler mReceiverHandler;
// Handler that all callbacks are made on.
@@ -179,6 +181,9 @@
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.registerListener();
}
+ if (mSubscriptionListener == null) {
+ mSubscriptionListener = new SubListener();
+ }
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
// broadcasts
@@ -422,7 +427,6 @@
: lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
}
});
- mCallbackHandler.setSubs(subscriptions);
mCurrentSubscriptions = subscriptions;
HashMap<Integer, MobileSignalController> cachedControllers =
@@ -455,6 +459,9 @@
cachedControllers.get(key).unregisterListener();
}
}
+ mCallbackHandler.setSubs(subscriptions);
+ notifyAllListeners();
+
// There may be new MobileSignalControllers around, make sure they get the current
// inet condition and airplane mode.
pushConnectivityToSignals();
@@ -724,13 +731,12 @@
return info;
}
- private final OnSubscriptionsChangedListener mSubscriptionListener =
- new OnSubscriptionsChangedListener() {
+ private class SubListener extends OnSubscriptionsChangedListener {
@Override
public void onSubscriptionsChanged() {
updateMobileControllers();
- };
- };
+ }
+ }
/**
* Used to register listeners from the BG Looper, this way the PhoneStateListeners that
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 962000a..b505d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -64,6 +64,7 @@
private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
private int mCurrentUserId;
+ private int mVpnUserId;
public SecurityControllerImpl(Context context) {
mContext = context;
@@ -78,7 +79,7 @@
// TODO: re-register network callback on user change.
mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
- mCurrentUserId = ActivityManager.getCurrentUser();
+ onUserSwitched(ActivityManager.getCurrentUser());
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -123,9 +124,9 @@
@Override
public String getPrimaryVpnName() {
- VpnConfig cfg = mCurrentVpns.get(mCurrentUserId);
+ VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
if (cfg != null) {
- return getNameForVpnConfig(cfg, new UserHandle(mCurrentUserId));
+ return getNameForVpnConfig(cfg, new UserHandle(mVpnUserId));
} else {
return null;
}
@@ -133,8 +134,8 @@
@Override
public String getProfileVpnName() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
- if (profile.id == mCurrentUserId) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
+ if (profile.id == mVpnUserId) {
continue;
}
VpnConfig cfg = mCurrentVpns.get(profile.id);
@@ -147,7 +148,7 @@
@Override
public boolean isVpnEnabled() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
if (mCurrentVpns.get(profile.id) != null) {
return true;
}
@@ -172,6 +173,12 @@
@Override
public void onUserSwitched(int newUserId) {
mCurrentUserId = newUserId;
+ if (mUserManager.getUserInfo(newUserId).isRestricted()) {
+ // VPN for a restricted profile is routed through its owner user
+ mVpnUserId = UserHandle.USER_OWNER;
+ } else {
+ mVpnUserId = mCurrentUserId;
+ }
fireCallbacks();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index 9d84a85..b2df40a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -36,6 +36,7 @@
ComponentName getEffectsSuppressor();
boolean isCountdownConditionSupported();
int getCurrentUser();
+ boolean isVolumeRestricted();
public static class Callback {
public void onZenChanged(int zen) {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 5b80ac2..c07f1a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -29,6 +29,7 @@
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.service.notification.Condition;
@@ -57,6 +58,7 @@
private final LinkedHashMap<Uri, Condition> mConditions = new LinkedHashMap<Uri, Condition>();
private final AlarmManager mAlarmManager;
private final SetupObserver mSetupObserver;
+ private final UserManager mUserManager;
private int mUserId;
private boolean mRequesting;
@@ -84,6 +86,13 @@
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mSetupObserver = new SetupObserver(handler);
mSetupObserver.register();
+ mUserManager = context.getSystemService(UserManager.class);
+ }
+
+ @Override
+ public boolean isVolumeRestricted() {
+ return mUserManager.hasUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME,
+ new UserHandle(mUserId));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 5700732..f98840b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1898,15 +1898,23 @@
boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
if (!mIsExpanded && !isHeadsUp) {
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
- } else if (isHeadsUp && (mAddedHeadsUpChildren.contains(row) || pinnedAndClosed)) {
- if (pinnedAndClosed || shouldHunAppearFromBottom(row)) {
- // Our custom add animation
- type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
- } else {
- // Normal add animation
- type = AnimationEvent.ANIMATION_TYPE_ADD;
+ } else {
+ StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
+ if (viewState == null) {
+ // A view state was never generated for this view, so we don't need to animate
+ // this. This may happen with notification children.
+ continue;
}
- onBottom = !pinnedAndClosed;
+ if (isHeadsUp && (mAddedHeadsUpChildren.contains(row) || pinnedAndClosed)) {
+ if (pinnedAndClosed || shouldHunAppearFromBottom(viewState)) {
+ // Our custom add animation
+ type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
+ } else {
+ // Normal add animation
+ type = AnimationEvent.ANIMATION_TYPE_ADD;
+ }
+ onBottom = !pinnedAndClosed;
+ }
}
AnimationEvent event = new AnimationEvent(row, type);
event.headsUpFromBottom = onBottom;
@@ -1916,8 +1924,7 @@
mAddedHeadsUpChildren.clear();
}
- private boolean shouldHunAppearFromBottom(ExpandableNotificationRow row) {
- StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
+ private boolean shouldHunAppearFromBottom(StackViewState viewState) {
if (viewState.yTranslation + viewState.height < mAmbientState.getMaxHeadsUpTranslation()) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 17e6e3d0..5b8fe89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -893,13 +893,12 @@
if (mHostLayout.indexOfChild(changingView) == -1) {
// This notification was actually removed, so we need to add it to the overlay
mHostLayout.getOverlay().add(changingView);
- ViewState viewState = new ViewState();
- viewState.initFrom(changingView);
- viewState.yTranslation = -changingView.getActualHeight();
+ mTmpState.initFrom(changingView);
+ mTmpState.yTranslation = -changingView.getActualHeight();
// We temporarily enable Y animations, the real filter will be combined
// afterwards anyway
mAnimationFilter.animateY = true;
- startViewAnimations(changingView, viewState, 0,
+ startViewAnimations(changingView, mTmpState, 0,
ANIMATION_DURATION_HEADS_UP_DISAPPEAR);
mChildrenToClearFromOverlay.add(changingView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index a5684a4..920b682 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -125,6 +125,11 @@
}
@Override
+ protected boolean isPanelFullyCollapsed() {
+ return false;
+ }
+
+ @Override
protected int getMaxKeyguardNotifications() {
return 0;
}
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/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index d360875..92cfaa1 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -318,11 +318,14 @@
private Notification onVolumeMounted(VolumeInfo vol) {
final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
-
- // Don't annoy when user dismissed in past
- if (rec.isSnoozed()) return null;
-
final DiskInfo disk = vol.getDisk();
+
+ // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we
+ // used to allow snoozing non-adoptable disks too.)
+ if (rec.isSnoozed() && disk.isAdoptable()) {
+ return null;
+ }
+
if (disk.isAdoptable() && !rec.isInited()) {
final CharSequence title = disk.getDescription();
final CharSequence text = mContext.getString(
@@ -346,7 +349,7 @@
R.string.ext_media_ready_notification_message, disk.getDescription());
final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
- return buildNotificationBuilder(vol, title, text)
+ final Notification.Builder builder = buildNotificationBuilder(vol, title, text)
.addAction(new Action(R.drawable.ic_folder_24dp,
mContext.getString(R.string.ext_media_browse_action),
browseIntent))
@@ -354,10 +357,14 @@
mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
- .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
.setCategory(Notification.CATEGORY_SYSTEM)
- .setPriority(Notification.PRIORITY_LOW)
- .build();
+ .setPriority(Notification.PRIORITY_LOW);
+ // Non-adoptable disks can't be snoozed.
+ if (disk.isAdoptable()) {
+ builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
+ }
+
+ return builder.build();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 81461bd..f432808 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -57,7 +57,7 @@
return mSelectedValue;
}
- public void setSelectedValue(Object value) {
+ public void setSelectedValue(Object value, boolean fromClick) {
if (Objects.equals(value, mSelectedValue)) return;
mSelectedValue = value;
for (int i = 0; i < getChildCount(); i++) {
@@ -67,7 +67,7 @@
c.setSelected(selected);
c.setTypeface(selected ? MEDIUM : REGULAR);
}
- fireOnSelected();
+ fireOnSelected(fromClick);
}
public void addButton(int labelResId, int contentDescriptionResId, Object value) {
@@ -100,9 +100,9 @@
}
}
- private void fireOnSelected() {
+ private void fireOnSelected(boolean fromClick) {
if (mCallback != null) {
- mCallback.onSelected(mSelectedValue);
+ mCallback.onSelected(mSelectedValue, fromClick);
}
}
@@ -115,11 +115,11 @@
private final View.OnClickListener mClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
- setSelectedValue(v.getTag());
+ setSelectedValue(v.getTag(), true /* fromClick */);
}
};
public interface Callback extends Interaction.Callback {
- void onSelected(Object value);
+ void onSelected(Object value, boolean fromClick);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Util.java b/packages/SystemUI/src/com/android/systemui/volume/Util.java
index 4214091..a46a44d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Util.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Util.java
@@ -16,11 +16,13 @@
package com.android.systemui.volume;
+import android.content.Context;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.VolumeProvider;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.PlaybackState;
+import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.TextView;
@@ -164,4 +166,9 @@
v.setVisibility(vis ? View.VISIBLE : View.INVISIBLE);
}
+ public static boolean isVoiceCapable(Context context) {
+ final TelephonyManager telephony =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ return telephony != null && telephony.isVoiceCapable();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 5b2eb84..3964820 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -111,6 +111,7 @@
private final Accessibility mAccessibility = new Accessibility();
private final ColorStateList mActiveSliderTint;
private final ColorStateList mInactiveSliderTint;
+ private final VolumeDialogMotion mMotion;
private boolean mShowing;
private boolean mExpanded;
@@ -120,9 +121,12 @@
private boolean mSilentMode = VolumePrefs.DEFAULT_ENABLE_SILENT_MODE;
private State mState;
private int mExpandButtonRes;
- private boolean mExpanding;
+ private boolean mExpandButtonAnimationRunning;
private SafetyWarningDialog mSafetyWarning;
private Callback mCallback;
+ private boolean mPendingStateChanged;
+ private boolean mPendingRecheckAll;
+ private long mCollapseTime;
public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
ZenModeController zenModeController, Callback callback) {
@@ -151,10 +155,10 @@
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle(VolumeDialog.class.getSimpleName());
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
- lp.windowAnimations = R.style.VolumeDialogAnimations;
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);
@@ -167,9 +171,22 @@
updateExpandButtonH();
mLayoutTransition = new LayoutTransition();
mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
- mLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
- mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
mDialogContentView.setLayoutTransition(mLayoutTransition);
+ mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView, mExpandButton,
+ new VolumeDialogMotion.Callback() {
+ @Override
+ public void onAnimatingChanged(boolean animating) {
+ if (animating) return;
+ if (mPendingStateChanged) {
+ mHandler.sendEmptyMessage(H.STATE_CHANGED);
+ mPendingStateChanged = false;
+ }
+ if (mPendingRecheckAll) {
+ mHandler.sendEmptyMessage(H.RECHECK_ALL);
+ mPendingRecheckAll = false;
+ }
+ }
+ });
addRow(AudioManager.STREAM_RING,
R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true);
@@ -241,6 +258,7 @@
final VolumeRow row = initRow(stream, iconRes, iconMuteRes, important);
if (!mRows.isEmpty()) {
final View v = new View(mContext);
+ v.setId(android.R.id.background);
final int h = mContext.getResources()
.getDimensionPixelSize(R.dimen.volume_slider_interspacing);
final LinearLayout.LayoutParams lp =
@@ -252,10 +270,11 @@
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
- if (D.BUG) Log.d(TAG, "onLayoutChange"
+ final boolean moved = oldLeft != left || oldTop != top;
+ if (D.BUG) Log.d(TAG, "onLayoutChange moved=" + moved
+ " old=" + new Rect(oldLeft, oldTop, oldRight, oldBottom).toShortString()
+ " new=" + new Rect(left,top,right,bottom).toShortString());
- if (oldLeft != left || oldTop != top) {
+ if (moved) {
for (int i = 0; i < mDialogContentView.getChildCount(); i++) {
final View c = mDialogContentView.getChildAt(i);
if (!c.isShown()) continue;
@@ -301,18 +320,21 @@
if (D.BUG) Log.d(TAG, "repositionExpandAnim x=" + x + " y=" + y);
mExpandButton.setTranslationX(x);
mExpandButton.setTranslationY(y);
+ mExpandButton.setTag((Integer) y);
}
public void dump(PrintWriter writer) {
writer.println(VolumeDialog.class.getSimpleName() + " state:");
writer.print(" mShowing: "); writer.println(mShowing);
writer.print(" mExpanded: "); writer.println(mExpanded);
- writer.print(" mExpanding: "); writer.println(mExpanding);
+ writer.print(" mExpandButtonAnimationRunning: ");
+ writer.println(mExpandButtonAnimationRunning);
writer.print(" mActiveStream: "); writer.println(mActiveStream);
writer.print(" mDynamic: "); writer.println(mDynamic);
writer.print(" mShowHeaders: "); writer.println(mShowHeaders);
writer.print(" mAutomute: "); writer.println(mAutomute);
writer.print(" mSilentMode: "); writer.println(mSilentMode);
+ writer.print(" mCollapseTime: "); writer.println(mCollapseTime);
writer.print(" mAccessibility.mFeedbackEnabled: ");
writer.println(mAccessibility.mFeedbackEnabled);
}
@@ -411,12 +433,13 @@
}
private void showH(int reason) {
+ if (D.BUG) Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
mHandler.removeMessages(H.SHOW);
mHandler.removeMessages(H.DISMISS);
rescheduleTimeoutH();
if (mShowing) return;
mShowing = true;
- mDialog.show();
+ mMotion.startShow();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
mController.notifyVisible(true);
}
@@ -433,7 +456,7 @@
private int computeTimeoutH() {
if (mAccessibility.mFeedbackEnabled) return 20000;
if (mSafetyWarning != null) return 5000;
- if (mExpanded || mExpanding) return 5000;
+ if (mExpanded || mExpandButtonAnimationRunning) return 5000;
if (mActiveStream == AudioManager.STREAM_MUSIC) return 1500;
return 3000;
}
@@ -443,9 +466,13 @@
mHandler.removeMessages(H.SHOW);
if (!mShowing) return;
mShowing = false;
- mDialog.dismiss();
+ mMotion.startDismiss(new Runnable() {
+ @Override
+ public void run() {
+ setExpandedH(false);
+ }
+ });
Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
- setExpandedH(false);
mController.notifyVisible(false);
synchronized (mSafetyWarningLock) {
if (mSafetyWarning != null) {
@@ -455,13 +482,40 @@
}
}
+ private void updateDialogBottomMarginH() {
+ final long diff = System.currentTimeMillis() - mCollapseTime;
+ final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
+ final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
+ final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
+ mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
+ if (bottomMargin != mlp.bottomMargin) {
+ if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
+ mlp.bottomMargin = bottomMargin;
+ mDialogView.setLayoutParams(mlp);
+ }
+ }
+
+ private long getConservativeCollapseDuration() {
+ return mExpandButtonAnimationDuration * 3;
+ }
+
+ private void prepareForCollapse() {
+ mHandler.removeMessages(H.UPDATE_BOTTOM_MARGIN);
+ mCollapseTime = System.currentTimeMillis();
+ updateDialogBottomMarginH();
+ mHandler.sendEmptyMessageDelayed(H.UPDATE_BOTTOM_MARGIN, getConservativeCollapseDuration());
+ }
+
private void setExpandedH(boolean expanded) {
if (mExpanded == expanded) return;
mExpanded = expanded;
- mExpanding = isAttached();
+ mExpandButtonAnimationRunning = isAttached();
if (D.BUG) Log.d(TAG, "setExpandedH " + expanded);
+ if (!mExpanded && mExpandButtonAnimationRunning) {
+ prepareForCollapse();
+ }
updateRowsH();
- if (mExpanding) {
+ if (mExpandButtonAnimationRunning) {
final Drawable d = mExpandButton.getDrawable();
if (d instanceof AnimatedVectorDrawable) {
// workaround to reset drawable
@@ -472,7 +526,7 @@
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mExpanding = false;
+ mExpandButtonAnimationRunning = false;
updateExpandButtonH();
rescheduleTimeoutH();
}
@@ -483,8 +537,9 @@
}
private void updateExpandButtonH() {
- mExpandButton.setClickable(!mExpanding);
- if (mExpanding && isAttached()) return;
+ if (D.BUG) Log.d(TAG, "updateExpandButtonH");
+ mExpandButton.setClickable(!mExpandButtonAnimationRunning);
+ if (mExpandButtonAnimationRunning && isAttached()) return;
final int res = mExpanded ? R.drawable.ic_volume_collapse_animation
: R.drawable.ic_volume_expand_animation;
if (res == mExpandButtonRes) return;
@@ -501,6 +556,7 @@
}
private void updateRowsH() {
+ if (D.BUG) Log.d(TAG, "updateRowsH");
final VolumeRow activeRow = getActiveRow();
updateFooterH();
updateExpandButtonH();
@@ -530,6 +586,7 @@
}
private void trimObsoleteH() {
+ if (D.BUG) Log.d(TAG, "trimObsoleteH");
for (int i = mRows.size() -1; i >= 0; i--) {
final VolumeRow row = mRows.get(i);
if (row.ss == null || !row.ss.dynamic) continue;
@@ -542,7 +599,13 @@
}
private void onStateChangedH(State state) {
+ final boolean animating = mMotion.isAnimating();
+ if (D.BUG) Log.d(TAG, "onStateChangedH animating=" + animating);
mState = state;
+ if (animating) {
+ mPendingStateChanged = true;
+ return;
+ }
mDynamic.clear();
// add any new dynamic rows
for (int i = 0; i < state.states.size(); i++) {
@@ -567,11 +630,18 @@
}
private void updateFooterH() {
- Util.setVisOrGone(mZenFooter, mState.zenMode != Global.ZEN_MODE_OFF);
+ if (D.BUG) Log.d(TAG, "updateFooterH");
+ final boolean wasVisible = mZenFooter.getVisibility() == View.VISIBLE;
+ final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF;
+ if (wasVisible != visible && !visible) {
+ prepareForCollapse();
+ }
+ Util.setVisOrGone(mZenFooter, visible);
mZenFooter.update();
}
private void updateVolumeRowH(VolumeRow row) {
+ if (D.BUG) Log.d(TAG, "updateVolumeRowH s=" + row.stream);
if (mState == null) return;
final StreamState ss = mState.states.get(row.stream);
if (ss == null) return;
@@ -670,6 +740,9 @@
}
private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
+ if (isActive && mExpanded) {
+ row.slider.requestFocus();
+ }
final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
: mInactiveSliderTint;
if (tint == row.cachedSliderTint) return;
@@ -832,7 +905,7 @@
private final OnClickListener mClickExpand = new OnClickListener() {
@Override
public void onClick(View v) {
- if (mExpanding) return;
+ if (mExpandButtonAnimationRunning) return;
final boolean newExpand = !mExpanded;
Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
setExpandedH(newExpand);
@@ -861,6 +934,8 @@
private static final int RECHECK_ALL = 4;
private static final int SET_STREAM_IMPORTANT = 5;
private static final int RESCHEDULE_TIMEOUT = 6;
+ private static final int STATE_CHANGED = 7;
+ private static final int UPDATE_BOTTOM_MARGIN = 8;
public H() {
super(Looper.getMainLooper());
@@ -875,6 +950,8 @@
case RECHECK_ALL: recheckH(null); break;
case SET_STREAM_IMPORTANT: setStreamImportantH(msg.arg1, msg.arg2 != 0); break;
case RESCHEDULE_TIMEOUT: rescheduleTimeoutH(); break;
+ case STATE_CHANGED: onStateChangedH(mState); break;
+ case UPDATE_BOTTOM_MARGIN: updateDialogBottomMarginH(); break;
}
}
}
@@ -893,6 +970,12 @@
@Override
protected void onStop() {
super.onStop();
+ final boolean animating = mMotion.isAnimating();
+ if (D.BUG) Log.d(TAG, "onStop animating=" + animating);
+ if (animating) {
+ mPendingRecheckAll = true;
+ return;
+ }
mHandler.sendEmptyMessage(H.RECHECK_ALL);
}
@@ -969,11 +1052,13 @@
mDialogView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewDetachedFromWindow(View v) {
+ if (D.BUG) Log.d(TAG, "onViewDetachedFromWindow");
// noop
}
@Override
public void onViewAttachedToWindow(View v) {
+ if (D.BUG) Log.d(TAG, "onViewAttachedToWindow");
updateFeedbackEnabled();
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 9a59a2a..32d6805 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -768,6 +768,7 @@
filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.registerReceiver(this, filter, null, mWorker);
}
@@ -822,6 +823,9 @@
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
if (D.BUG) Log.d(TAG, "onReceive ACTION_SCREEN_OFF");
mCallbacks.onScreenOff();
+ } else if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
+ if (D.BUG) Log.d(TAG, "onReceive ACTION_CLOSE_SYSTEM_DIALOGS");
+ dismiss();
}
if (changed) {
mCallbacks.onStateChanged(mState);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
new file mode 100644
index 0000000..4bb1011
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -0,0 +1,313 @@
+/*
+ * 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.systemui.volume;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.DialogInterface.OnShowListener;
+import android.os.Handler;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.PathInterpolator;
+
+public class VolumeDialogMotion {
+ private static final String TAG = Util.logTag(VolumeDialogMotion.class);
+
+ private static final float ANIMATION_SCALE = 1.0f;
+ private static final int PRE_DISMISS_DELAY = 50;
+ private static final int POST_SHOW_DELAY = 200;
+
+ private final Dialog mDialog;
+ private final View mDialogView;
+ private final ViewGroup mContents; // volume rows + zen footer
+ private final View mChevron;
+ private final Handler mHandler = new Handler();
+ private final Callback mCallback;
+
+ private boolean mAnimating; // show or dismiss animation is running
+ private boolean mShowing; // show animation is running
+ private boolean mDismissing; // dismiss animation is running
+ private ValueAnimator mChevronPositionAnimator;
+ private ValueAnimator mContentsPositionAnimator;
+
+ public VolumeDialogMotion(Dialog dialog, View dialogView, ViewGroup contents, View chevron,
+ Callback callback) {
+ mDialog = dialog;
+ mDialogView = dialogView;
+ mContents = contents;
+ mChevron = chevron;
+ mCallback = callback;
+ mDialog.setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (D.BUG) Log.d(TAG, "mDialog.onDismiss");
+ }
+ });
+ mDialog.setOnShowListener(new OnShowListener() {
+ @Override
+ public void onShow(DialogInterface dialog) {
+ if (D.BUG) Log.d(TAG, "mDialog.onShow");
+ final int h = mDialogView.getHeight();
+ mDialogView.setTranslationY(-h);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ startShowAnimation();
+ }
+ }, POST_SHOW_DELAY);
+ }
+ });
+ }
+
+ public boolean isAnimating() {
+ return mAnimating;
+ }
+
+ private void setShowing(boolean showing) {
+ if (showing == mShowing) return;
+ mShowing = showing;
+ if (D.BUG) Log.d(TAG, "mShowing = " + mShowing);
+ updateAnimating();
+ }
+
+ private void setDismissing(boolean dismissing) {
+ if (dismissing == mDismissing) return;
+ mDismissing = dismissing;
+ if (D.BUG) Log.d(TAG, "mDismissing = " + mDismissing);
+ updateAnimating();
+ }
+
+ private void updateAnimating() {
+ final boolean animating = mShowing || mDismissing;
+ if (animating == mAnimating) return;
+ mAnimating = animating;
+ if (D.BUG) Log.d(TAG, "mAnimating = " + mAnimating);
+ if (mCallback != null) {
+ mCallback.onAnimatingChanged(mAnimating);
+ }
+ }
+
+ public void startShow() {
+ if (D.BUG) Log.d(TAG, "startShow");
+ if (mShowing) return;
+ setShowing(true);
+ if (mDismissing) {
+ mDialogView.animate().cancel();
+ setDismissing(false);
+ startShowAnimation();
+ return;
+ }
+ if (D.BUG) Log.d(TAG, "mDialog.show()");
+ mDialog.show();
+ }
+
+ private int chevronDistance() {
+ return mChevron.getHeight() / 6;
+ }
+
+ private int chevronPosY() {
+ final Object tag = mChevron == null ? null : mChevron.getTag();
+ return tag == null ? 0 : (Integer) tag;
+ }
+
+ private void startShowAnimation() {
+ if (D.BUG) Log.d(TAG, "startShowAnimation");
+ mDialogView.animate()
+ .translationY(0)
+ .setDuration(scaledDuration(300))
+ .setInterpolator(new LogDecelerateInterpolator())
+ .setListener(null)
+ .setUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (mChevronPositionAnimator == null) return;
+ // reposition chevron
+ final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
+ final int posY = chevronPosY();
+ mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
+ }})
+ .start();
+
+ mContentsPositionAnimator = ValueAnimator.ofFloat(-chevronDistance(), 0)
+ .setDuration(scaledDuration(400));
+ mContentsPositionAnimator.addListener(new AnimatorListenerAdapter() {
+ private boolean mCancelled;
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mCancelled) return;
+ if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
+ setShowing(false);
+ }
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
+ mCancelled = true;
+ }
+ });
+ mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float v = (Float) animation.getAnimatedValue();
+ mContents.setTranslationY(v + -mDialogView.getTranslationY());
+ }
+ });
+ mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
+ mContentsPositionAnimator.start();
+
+ mContents.setAlpha(0);
+ mContents.animate()
+ .alpha(1)
+ .setDuration(scaledDuration(150))
+ .setInterpolator(new PathInterpolator(0f, 0f, .2f, 1f))
+ .start();
+
+ mChevronPositionAnimator = ValueAnimator.ofFloat(-chevronDistance(), 0)
+ .setDuration(scaledDuration(250));
+ mChevronPositionAnimator.setInterpolator(new PathInterpolator(.4f, 0f, .2f, 1f));
+ mChevronPositionAnimator.start();
+
+ mChevron.setAlpha(0);
+ mChevron.animate()
+ .alpha(1)
+ .setStartDelay(scaledDuration(50))
+ .setDuration(scaledDuration(150))
+ .setInterpolator(new PathInterpolator(.4f, 0f, 1f, 1f))
+ .start();
+ }
+
+ public void startDismiss(final Runnable onComplete) {
+ if (D.BUG) Log.d(TAG, "startDismiss");
+ if (mDismissing) return;
+ setDismissing(true);
+ if (mShowing) {
+ mDialogView.animate().cancel();
+ if (mContentsPositionAnimator != null) {
+ mContentsPositionAnimator.cancel();
+ }
+ mContents.animate().cancel();
+ if (mChevronPositionAnimator != null) {
+ mChevronPositionAnimator.cancel();
+ }
+ mChevron.animate().cancel();
+ setShowing(false);
+ }
+ mDialogView.animate()
+ .translationY(-mDialogView.getHeight())
+ .setDuration(scaledDuration(250))
+ .setInterpolator(new LogAccelerateInterpolator())
+ .setUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mContents.setTranslationY(-mDialogView.getTranslationY());
+ final int posY = chevronPosY();
+ mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
+ }
+ })
+ .setListener(new AnimatorListenerAdapter() {
+ private boolean mCancelled;
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mCancelled) return;
+ if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
+ mDialog.dismiss();
+ onComplete.run();
+ setDismissing(false);
+ }
+ }, PRE_DISMISS_DELAY);
+
+ }
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
+ mCancelled = true;
+ }
+ }).start();
+ }
+
+ private static int scaledDuration(int base) {
+ return (int) (base * ANIMATION_SCALE);
+ }
+
+ private static final class LogDecelerateInterpolator implements TimeInterpolator {
+ private final float mBase;
+ private final float mDrift;
+ private final float mTimeScale;
+ private final float mOutputScale;
+
+ private LogDecelerateInterpolator() {
+ this(400f, 1.4f, 0);
+ }
+
+ private LogDecelerateInterpolator(float base, float timeScale, float drift) {
+ mBase = base;
+ mDrift = drift;
+ mTimeScale = 1f / timeScale;
+
+ mOutputScale = 1f / computeLog(1f);
+ }
+
+ private float computeLog(float t) {
+ return 1f - (float) Math.pow(mBase, -t * mTimeScale) + (mDrift * t);
+ }
+
+ @Override
+ public float getInterpolation(float t) {
+ return computeLog(t) * mOutputScale;
+ }
+ }
+
+ private static final class LogAccelerateInterpolator implements TimeInterpolator {
+ private final int mBase;
+ private final int mDrift;
+ private final float mLogScale;
+
+ private LogAccelerateInterpolator() {
+ this(100, 0);
+ }
+
+ private LogAccelerateInterpolator(int base, int drift) {
+ mBase = base;
+ mDrift = drift;
+ mLogScale = 1f / computeLog(1, mBase, mDrift);
+ }
+
+ private static float computeLog(float t, int base, int drift) {
+ return (float) -Math.pow(base, -t) + 1 + (drift * t);
+ }
+
+ @Override
+ public float getInterpolation(float t) {
+ return 1 - computeLog(1 - t, mBase, mDrift) * mLogScale;
+ }
+ }
+
+ public interface Callback {
+ void onAnimatingChanged(boolean animating);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 3f6294d..af7ee08 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -16,6 +16,7 @@
package com.android.systemui.volume;
import android.animation.LayoutTransition;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
@@ -51,7 +52,9 @@
super(context, attrs);
mContext = context;
mSpTexts = new SpTexts(mContext);
- setLayoutTransition(new LayoutTransition());
+ final LayoutTransition layoutTransition = new LayoutTransition();
+ layoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
+ setLayoutTransition(layoutTransition);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index a0eb61f..3c9a7fc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -118,6 +118,7 @@
private Condition mSessionExitCondition;
private Condition[] mConditions;
private Condition mTimeCondition;
+ private boolean mVoiceCapable;
public ZenModePanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -127,6 +128,7 @@
mIconPulser = new IconPulser(mContext);
mForeverId = Condition.newId(mContext).appendPath("forever").build();
mSpTexts = new SpTexts(mContext);
+ mVoiceCapable = Util.isVoiceCapable(mContext);
if (DEBUG) Log.d(mTag, "new ZenModePanel");
}
@@ -144,6 +146,7 @@
pw.println(mPrefs.mConfirmedPriorityIntroduction);
pw.print(" mConfirmedSilenceIntroduction=");
pw.println(mPrefs.mConfirmedSilenceIntroduction);
+ pw.print(" mVoiceCapable="); pw.println(mVoiceCapable);
mTransitionHelper.dump(fd, pw, args);
}
@@ -388,7 +391,7 @@
setExpanded(isShown());
mSessionZen = zen;
}
- mZenButtons.setSelectedValue(zen);
+ mZenButtons.setSelectedValue(zen, false /* fromClick */);
updateWidgets();
handleUpdateConditions();
if (mExpanded) {
@@ -444,6 +447,7 @@
mZenIntroduction.setVisibility(introduction ? VISIBLE : GONE);
if (introduction) {
mZenIntroductionMessage.setText(zenImportant ? R.string.zen_priority_introduction
+ : mVoiceCapable ? R.string.zen_silence_introduction_voice
: R.string.zen_silence_introduction);
mZenIntroductionCustomize.setVisibility(zenImportant ? VISIBLE : GONE);
}
@@ -964,10 +968,12 @@
private final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
@Override
- public void onSelected(final Object value) {
+ public void onSelected(final Object value, boolean fromClick) {
if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
final int zen = (Integer) value;
- MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ if (fromClick) {
+ MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+ }
if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
final Uri realConditionId = getRealConditionId(mSessionExitCondition);
AsyncTask.execute(new Runnable() {
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 32e1e6d..375c5d8 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -24,7 +24,7 @@
<application android:label="VpnDialogs"
android:allowBackup="false" >
<activity android:name=".ConfirmDialog"
- android:theme="@*android:style/Theme.Material.DayNight.Dialog.Alert">
+ android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
@@ -32,7 +32,7 @@
</activity>
<activity android:name=".ManageDialog"
- android:theme="@*android:style/Theme.Material.DayNight.Dialog.Alert"
+ android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
diff --git a/packages/WallpaperCropper/res/values/styles.xml b/packages/WallpaperCropper/res/values/styles.xml
index e438c84..a34b25a 100644
--- a/packages/WallpaperCropper/res/values/styles.xml
+++ b/packages/WallpaperCropper/res/values/styles.xml
@@ -15,13 +15,13 @@
-->
<resources>
- <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Material.DayNight">
+ <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
<item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowActionBarOverlay">true</item>
</style>
- <style name="WallpaperCropperActionBar" parent="@android:style/Widget.Material.ActionBar">
+ <style name="WallpaperCropperActionBar" parent="android:style/Widget.DeviceDefault.ActionBar">
<item name="android:displayOptions">showCustom</item>
<item name="android:background">#88000000</item>
</style>
diff --git a/preloaded-classes b/preloaded-classes
index 41a8857..4d7a6e1 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1,7 +1,4 @@
# Classes which are preloaded by com.android.internal.os.ZygoteInit.
-# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.
-# MIN_LOAD_TIME_MICROS=1250
-# MIN_PROCESSES=10
[B
[C
[D
@@ -12,12 +9,13 @@
[Landroid.animation.Animator;
[Landroid.animation.Keyframe$FloatKeyframe;
[Landroid.animation.Keyframe$IntKeyframe;
+[Landroid.animation.Keyframe$ObjectKeyframe;
[Landroid.animation.PropertyValuesHolder;
-[Landroid.app.FragmentState;
[Landroid.app.LoaderManagerImpl;
[Landroid.content.ContentProviderResult;
[Landroid.content.ContentValues;
[Landroid.content.Intent;
+[Landroid.content.UndoOwner;
[Landroid.content.pm.ActivityInfo;
[Landroid.content.pm.ConfigurationInfo;
[Landroid.content.pm.FeatureGroupInfo;
@@ -30,9 +28,9 @@
[Landroid.content.pm.Signature;
[Landroid.content.res.StringBlock;
[Landroid.content.res.XmlBlock;
+[Landroid.database.CursorWindow;
[Landroid.database.sqlite.SQLiteConnection$Operation;
[Landroid.database.sqlite.SQLiteConnectionPool$AcquiredConnectionStatus;
-[Landroid.graphics.Bitmap$CompressFormat;
[Landroid.graphics.Bitmap$Config;
[Landroid.graphics.Canvas$EdgeType;
[Landroid.graphics.FontFamily;
@@ -51,13 +49,39 @@
[Landroid.graphics.drawable.Drawable;
[Landroid.graphics.drawable.GradientDrawable$Orientation;
[Landroid.graphics.drawable.LayerDrawable$ChildDrawable;
-[Landroid.graphics.drawable.Ripple;
+[Landroid.graphics.drawable.RippleForeground;
[Landroid.hardware.soundtrigger.SoundTrigger$ConfidenceLevel;
[Landroid.hardware.soundtrigger.SoundTrigger$Keyphrase;
[Landroid.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra;
+[Landroid.icu.impl.ICUResourceBundle$OpenType;
+[Landroid.icu.impl.Trie2$ValueWidth;
+[Landroid.icu.impl.UCharacterProperty$BinaryProperty;
+[Landroid.icu.impl.UCharacterProperty$IntProperty;
+[Landroid.icu.lang.UScript$ScriptUsage;
+[Landroid.icu.text.DateFormat$BooleanAttribute;
+[Landroid.icu.text.DateFormat$Field;
+[Landroid.icu.text.DateFormatSymbols$CapitalizationContextUsage;
+[Landroid.icu.text.DateTimePatternGenerator$DTPGflags;
+[Landroid.icu.text.DisplayContext$Type;
+[Landroid.icu.text.DisplayContext;
+[Landroid.icu.text.MessagePattern$ApostropheMode;
+[Landroid.icu.text.MessagePattern$ArgType;
+[Landroid.icu.text.MessagePattern$Part$Type;
+[Landroid.icu.text.UnicodeSet;
+[Landroid.icu.util.BytesTrie$Result;
+[Landroid.icu.util.Calendar$CalType;
+[Landroid.icu.util.ULocale$Category;
+[Landroid.icu.util.ULocale;
+[Landroid.media.AudioDeviceInfo;
[Landroid.media.AudioGain;
+[Landroid.media.AudioPatch;
+[Landroid.media.AudioPort;
+[Landroid.media.AudioPortConfig;
+[Landroid.media.MediaTimeProvider$OnMediaTimeListener;
[Landroid.net.NetworkInfo$DetailedState;
[Landroid.net.NetworkInfo$State;
+[Landroid.net.Uri;
+[Landroid.net.wifi.SupplicantState;
[Landroid.os.AsyncTask$Status;
[Landroid.os.MessageQueue$IdleHandler;
[Landroid.os.Parcel;
@@ -86,51 +110,92 @@
[Landroid.text.style.ReplacementSpan;
[Landroid.text.style.SpellCheckSpan;
[Landroid.text.style.SuggestionSpan;
+[Landroid.text.style.TabStopSpan;
+[Landroid.text.style.URLSpan;
[Landroid.text.style.WrapTogetherSpan;
[Landroid.util.LongSparseArray;
[Landroid.util.PathParser$PathDataNode;
[Landroid.view.Choreographer$CallbackQueue;
+[Landroid.view.Display$Mode;
+[Landroid.view.MenuItem;
[Landroid.view.View;
-[Landroid.widget.Editor$TextDisplayList;
+[Landroid.widget.Editor$TextRenderNode;
[Landroid.widget.Editor$TextViewPositionListener;
[Landroid.widget.ImageView$ScaleType;
+[Landroid.widget.SpellChecker$SpellParser;
[Landroid.widget.TextView$BufferType;
[Landroid.widget.TextView$ChangeWatcher;
[Lcom.android.dex.TableOfContents$Section;
-[Lcom.android.internal.policy.impl.PhoneWindow$PanelFeatureState;
+[Lcom.android.internal.policy.PhoneWindow$PanelFeatureState;
[Lcom.android.internal.telephony.PhoneConstants$State;
+[Lcom.android.okhttp.CipherSuite;
+[Lcom.android.okhttp.ConnectionSpec;
[Lcom.android.okhttp.Protocol;
-[Lcom.android.okhttp.ResponseSource;
-[Lcom.android.okhttp.internal.http.HttpURLConnectionImpl$Retry;
+[Lcom.android.okhttp.TlsVersion;
[Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+[Lcom.android.org.bouncycastle.asn1.x500.RDN;
[Lcom.android.org.bouncycastle.asn1.x509.GeneralName;
[Lcom.android.org.conscrypt.OpenSSLX509CertPath$Encoding;
[Lcom.android.org.conscrypt.OpenSSLX509Certificate;
+[Ldalvik.system.DexPathList$Element;
+[Ljava.io.File;
[Ljava.io.FileDescriptor;
+[Ljava.io.IOException;
+[Ljava.io.ObjectStreamField;
+[Ljava.lang.Byte;
[Ljava.lang.CharSequence;
+[Ljava.lang.Character$UnicodeBlock;
+[Ljava.lang.Character;
[Ljava.lang.Class;
+[Ljava.lang.Enum;
[Ljava.lang.Integer;
+[Ljava.lang.Long;
[Ljava.lang.Object;
+[Ljava.lang.Package;
[Ljava.lang.Runnable;
+[Ljava.lang.Short;
+[Ljava.lang.StackTraceElement;
[Ljava.lang.String;
+[Ljava.lang.Thread$State;
+[Ljava.lang.Thread;
+[Ljava.lang.ThreadGroup;
+[Ljava.lang.Throwable;
[Ljava.lang.Void;
+[Ljava.lang.annotation.Annotation;
+[Ljava.lang.reflect.AccessibleObject;
+[Ljava.lang.reflect.Constructor;
+[Ljava.lang.reflect.Field;
+[Ljava.lang.reflect.Method;
+[Ljava.lang.reflect.Type;
+[Ljava.lang.reflect.TypeVariable;
[Ljava.math.BigDecimal;
[Ljava.math.BigInteger;
[Ljava.math.RoundingMode;
[Ljava.net.InetAddress;
[Ljava.net.Proxy$Type;
+[Ljava.security.Provider;
+[Ljava.security.cert.Certificate;
[Ljava.security.cert.X509Certificate;
[Ljava.text.Format$Field;
[Ljava.util.ArrayList;
+[Ljava.util.HashMap$HashMapEntry;
+[Ljava.util.Hashtable$HashtableEntry;
+[Ljava.util.Locale;
[Ljava.util.Map$Entry;
[Ljava.util.TimerTask;
+[Ljava.util.TreeMap$Bound;
[Ljava.util.TreeMap$Relation;
+[Ljava.util.WeakHashMap$Entry;
[Ljava.util.concurrent.ConcurrentHashMap$Node;
[Ljava.util.concurrent.ConcurrentHashMap$Segment;
+[Ljava.util.concurrent.RunnableScheduledFuture;
[Ljava.util.concurrent.TimeUnit;
[Ljava.util.logging.Handler;
+[Ljava.util.regex.Pattern;
+[Ljavax.crypto.Cipher$NeedToSet;
[Ljavax.net.ssl.KeyManager;
[Ljavax.net.ssl.TrustManager;
+[Ljavax.security.cert.X509Certificate;
[Llibcore.reflect.AnnotationMember$DefaultValues;
[Llibcore.reflect.AnnotationMember;
[Lorg.apache.harmony.security.asn1.ASN1Type;
@@ -142,20 +207,25 @@
[Lorg.apache.http.conn.routing.RouteInfo$TunnelType;
[Lorg.json.JSONStringer$Scope;
[Lorg.kxml2.io.KXmlParser$ValueContext;
+[S
[Z
[[B
+[[C
[[I
[[Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+[[Ljava.lang.Class;
[[Ljava.lang.Object;
[[Ljava.lang.String;
+[[Ljava.lang.annotation.Annotation;
[[Lorg.apache.harmony.security.utils.ObjectIdentifier;
-[[[B
+[[S
+[[[I
android.R$styleable
android.accounts.Account
android.accounts.Account$1
android.accounts.AccountManager
-android.accounts.AccountManager$16
-android.accounts.AccountManager$8
+android.accounts.AccountManager$1
+android.accounts.AccountManager$11
android.accounts.AccountManager$AmsTask
android.accounts.AccountManager$AmsTask$1
android.accounts.AccountManager$AmsTask$Response
@@ -171,6 +241,7 @@
android.accounts.OnAccountsUpdateListener
android.accounts.OperationCanceledException
android.animation.Animator
+android.animation.Animator$AnimatorConstantState
android.animation.Animator$AnimatorListener
android.animation.Animator$AnimatorPauseListener
android.animation.AnimatorInflater
@@ -181,6 +252,7 @@
android.animation.AnimatorSet$Dependency
android.animation.AnimatorSet$DependencyListener
android.animation.AnimatorSet$Node
+android.animation.ArgbEvaluator
android.animation.FloatEvaluator
android.animation.FloatKeyframeSet
android.animation.IntEvaluator
@@ -188,6 +260,7 @@
android.animation.Keyframe
android.animation.Keyframe$FloatKeyframe
android.animation.Keyframe$IntKeyframe
+android.animation.Keyframe$ObjectKeyframe
android.animation.KeyframeSet
android.animation.Keyframes
android.animation.Keyframes$FloatKeyframes
@@ -195,22 +268,30 @@
android.animation.LayoutTransition
android.animation.LayoutTransition$TransitionListener
android.animation.ObjectAnimator
+android.animation.PathKeyframes
+android.animation.PathKeyframes$1
+android.animation.PathKeyframes$2
+android.animation.PathKeyframes$FloatKeyframesBase
+android.animation.PathKeyframes$SimpleKeyframes
android.animation.PropertyValuesHolder
android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
android.animation.PropertyValuesHolder$IntPropertyValuesHolder
android.animation.RectEvaluator
android.animation.StateListAnimator
android.animation.StateListAnimator$1
+android.animation.StateListAnimator$StateListAnimatorConstantState
android.animation.StateListAnimator$Tuple
android.animation.TimeInterpolator
android.animation.TypeEvaluator
android.animation.ValueAnimator
android.animation.ValueAnimator$AnimationHandler
+android.animation.ValueAnimator$AnimationHandler$1
+android.animation.ValueAnimator$AnimationHandler$2
android.animation.ValueAnimator$AnimatorUpdateListener
android.app.ActionBar
android.app.ActionBar$LayoutParams
android.app.Activity
-android.app.Activity$1
+android.app.Activity$HostCallbacks
android.app.ActivityManager
android.app.ActivityManager$RunningAppProcessInfo
android.app.ActivityManager$RunningAppProcessInfo$1
@@ -244,6 +325,7 @@
android.app.ActivityThread$StopInfo
android.app.ActivityTransitionState
android.app.AlertDialog
+android.app.AlertDialog$Builder
android.app.AppGlobals
android.app.AppOpsManager
android.app.Application
@@ -257,91 +339,21 @@
android.app.BackStackRecord$Op
android.app.BackStackRecord$TransitionState
android.app.ContextImpl
-android.app.ContextImpl$1
-android.app.ContextImpl$10
-android.app.ContextImpl$11
-android.app.ContextImpl$12
-android.app.ContextImpl$13
-android.app.ContextImpl$14
-android.app.ContextImpl$15
-android.app.ContextImpl$16
-android.app.ContextImpl$17
-android.app.ContextImpl$18
-android.app.ContextImpl$19
-android.app.ContextImpl$2
-android.app.ContextImpl$20
-android.app.ContextImpl$21
-android.app.ContextImpl$22
-android.app.ContextImpl$23
-android.app.ContextImpl$24
-android.app.ContextImpl$25
-android.app.ContextImpl$26
-android.app.ContextImpl$27
-android.app.ContextImpl$28
-android.app.ContextImpl$29
-android.app.ContextImpl$3
-android.app.ContextImpl$30
-android.app.ContextImpl$31
-android.app.ContextImpl$32
-android.app.ContextImpl$33
-android.app.ContextImpl$34
-android.app.ContextImpl$35
-android.app.ContextImpl$36
-android.app.ContextImpl$37
-android.app.ContextImpl$38
-android.app.ContextImpl$39
-android.app.ContextImpl$4
-android.app.ContextImpl$40
-android.app.ContextImpl$41
-android.app.ContextImpl$42
-android.app.ContextImpl$43
-android.app.ContextImpl$44
-android.app.ContextImpl$45
-android.app.ContextImpl$46
-android.app.ContextImpl$47
-android.app.ContextImpl$48
-android.app.ContextImpl$49
-android.app.ContextImpl$5
-android.app.ContextImpl$50
-android.app.ContextImpl$51
-android.app.ContextImpl$52
-android.app.ContextImpl$53
-android.app.ContextImpl$54
-android.app.ContextImpl$55
-android.app.ContextImpl$56
-android.app.ContextImpl$57
-android.app.ContextImpl$58
-android.app.ContextImpl$59
-android.app.ContextImpl$6
-android.app.ContextImpl$60
-android.app.ContextImpl$61
-android.app.ContextImpl$62
-android.app.ContextImpl$7
-android.app.ContextImpl$8
-android.app.ContextImpl$9
android.app.ContextImpl$ApplicationContentResolver
-android.app.ContextImpl$ServiceFetcher
-android.app.ContextImpl$StaticServiceFetcher
android.app.Dialog
android.app.Dialog$1
android.app.Dialog$ListenersHandler
-android.app.DialogFragment
+android.app.DownloadManager
android.app.Fragment
android.app.Fragment$1
-android.app.FragmentBreadCrumbs
android.app.FragmentContainer
+android.app.FragmentController
+android.app.FragmentHostCallback
android.app.FragmentManager
android.app.FragmentManager$BackStackEntry
android.app.FragmentManagerImpl
android.app.FragmentManagerImpl$1
-android.app.FragmentManagerState
-android.app.FragmentManagerState$1
-android.app.FragmentState
-android.app.FragmentState$1
android.app.FragmentTransaction
-android.app.IActivityContainer
-android.app.IActivityContainer$Stub
-android.app.IActivityContainer$Stub$Proxy
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
android.app.IActivityManager$ContentProviderHolder$1
@@ -362,6 +374,7 @@
android.app.IntentReceiverLeaked
android.app.IntentService
android.app.IntentService$ServiceHandler
+android.app.KeyguardManager
android.app.ListActivity
android.app.LoadedApk
android.app.LoadedApk$ReceiverDispatcher
@@ -385,7 +398,6 @@
android.app.PendingIntent
android.app.PendingIntent$1
android.app.PendingIntent$CanceledException
-android.app.ProgressDialog
android.app.QueuedWork
android.app.ReceiverRestrictedContext
android.app.ResourcesManager
@@ -402,8 +414,83 @@
android.app.SharedPreferencesImpl$EditorImpl$1
android.app.SharedPreferencesImpl$EditorImpl$2
android.app.SharedPreferencesImpl$MemoryCommitResult
+android.app.StatusBarManager
android.app.SystemServiceRegistry
+android.app.SystemServiceRegistry$1
+android.app.SystemServiceRegistry$10
+android.app.SystemServiceRegistry$11
+android.app.SystemServiceRegistry$12
+android.app.SystemServiceRegistry$13
+android.app.SystemServiceRegistry$14
+android.app.SystemServiceRegistry$15
+android.app.SystemServiceRegistry$16
+android.app.SystemServiceRegistry$17
+android.app.SystemServiceRegistry$18
+android.app.SystemServiceRegistry$19
+android.app.SystemServiceRegistry$2
+android.app.SystemServiceRegistry$20
+android.app.SystemServiceRegistry$21
+android.app.SystemServiceRegistry$22
+android.app.SystemServiceRegistry$23
+android.app.SystemServiceRegistry$24
+android.app.SystemServiceRegistry$25
+android.app.SystemServiceRegistry$26
+android.app.SystemServiceRegistry$27
+android.app.SystemServiceRegistry$28
+android.app.SystemServiceRegistry$29
+android.app.SystemServiceRegistry$3
+android.app.SystemServiceRegistry$30
+android.app.SystemServiceRegistry$31
+android.app.SystemServiceRegistry$32
+android.app.SystemServiceRegistry$33
+android.app.SystemServiceRegistry$34
+android.app.SystemServiceRegistry$35
+android.app.SystemServiceRegistry$36
+android.app.SystemServiceRegistry$37
+android.app.SystemServiceRegistry$38
+android.app.SystemServiceRegistry$39
+android.app.SystemServiceRegistry$4
+android.app.SystemServiceRegistry$40
+android.app.SystemServiceRegistry$41
+android.app.SystemServiceRegistry$42
+android.app.SystemServiceRegistry$43
+android.app.SystemServiceRegistry$44
+android.app.SystemServiceRegistry$45
+android.app.SystemServiceRegistry$46
+android.app.SystemServiceRegistry$47
+android.app.SystemServiceRegistry$48
+android.app.SystemServiceRegistry$49
+android.app.SystemServiceRegistry$5
+android.app.SystemServiceRegistry$50
+android.app.SystemServiceRegistry$51
+android.app.SystemServiceRegistry$52
+android.app.SystemServiceRegistry$53
+android.app.SystemServiceRegistry$54
+android.app.SystemServiceRegistry$55
+android.app.SystemServiceRegistry$56
+android.app.SystemServiceRegistry$57
+android.app.SystemServiceRegistry$58
+android.app.SystemServiceRegistry$59
+android.app.SystemServiceRegistry$6
+android.app.SystemServiceRegistry$60
+android.app.SystemServiceRegistry$61
+android.app.SystemServiceRegistry$62
+android.app.SystemServiceRegistry$63
+android.app.SystemServiceRegistry$64
+android.app.SystemServiceRegistry$65
+android.app.SystemServiceRegistry$66
+android.app.SystemServiceRegistry$67
+android.app.SystemServiceRegistry$68
+android.app.SystemServiceRegistry$7
+android.app.SystemServiceRegistry$8
+android.app.SystemServiceRegistry$9
+android.app.SystemServiceRegistry$CachedServiceFetcher
+android.app.SystemServiceRegistry$ServiceFetcher
+android.app.SystemServiceRegistry$StaticServiceFetcher
+android.app.UiModeManager
+android.app.WallpaperManager
android.app.admin.DevicePolicyManager
+android.app.admin.IDevicePolicyManager
android.app.admin.IDevicePolicyManager$Stub
android.app.admin.IDevicePolicyManager$Stub$Proxy
android.app.backup.BackupDataInput
@@ -411,19 +498,44 @@
android.app.backup.BackupDataOutput
android.app.backup.BackupHelperDispatcher
android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.BackupManager
android.app.backup.FileBackupHelperBase
android.app.backup.FullBackup
-android.appwidget.AppWidgetHostView
+android.app.backup.FullBackupDataOutput
+android.app.backup.IBackupManager
+android.app.backup.IBackupManager$Stub
+android.app.backup.IBackupManager$Stub$Proxy
+android.app.job.JobScheduler
+android.app.trust.ITrustManager
+android.app.trust.ITrustManager$Stub
+android.app.trust.ITrustManager$Stub$Proxy
+android.app.trust.TrustManager
+android.app.usage.NetworkStatsManager
+android.app.usage.UsageStatsManager
android.appwidget.AppWidgetManager
android.appwidget.AppWidgetProvider
-android.bluetooth.BluetoothDevice
-android.bluetooth.BluetoothUuid
+android.bluetooth.BluetoothAdapter
+android.bluetooth.BluetoothAdapter$1
+android.bluetooth.BluetoothManager
+android.bluetooth.IBluetooth
+android.bluetooth.IBluetooth$Stub
+android.bluetooth.IBluetooth$Stub$Proxy
+android.bluetooth.IBluetoothManager
+android.bluetooth.IBluetoothManager$Stub
+android.bluetooth.IBluetoothManager$Stub$Proxy
+android.bluetooth.IBluetoothManagerCallback
+android.bluetooth.IBluetoothManagerCallback$Stub
android.content.AbstractThreadedSyncAdapter
android.content.AbstractThreadedSyncAdapter$ISyncAdapterImpl
android.content.AbstractThreadedSyncAdapter$SyncThread
android.content.ActivityNotFoundException
android.content.BroadcastReceiver
android.content.BroadcastReceiver$PendingResult
+android.content.BroadcastReceiver$PendingResult$1
+android.content.ClipData
+android.content.ClipDescription
+android.content.ClipDescription$1
+android.content.ClipboardManager
android.content.ComponentCallbacks
android.content.ComponentCallbacks2
android.content.ComponentName
@@ -468,8 +580,10 @@
android.content.IntentFilter
android.content.IntentFilter$1
android.content.IntentFilter$MalformedMimeTypeException
+android.content.IntentSender
android.content.IntentSender$SendIntentException
android.content.OperationApplicationException
+android.content.RestrictionsManager
android.content.ServiceConnection
android.content.SharedPreferences
android.content.SharedPreferences$Editor
@@ -482,6 +596,10 @@
android.content.SyncResult$1
android.content.SyncStats
android.content.SyncStats$1
+android.content.UndoManager
+android.content.UndoManager$UndoState
+android.content.UndoOperation
+android.content.UndoOwner
android.content.UriMatcher
android.content.pm.ActivityInfo
android.content.pm.ActivityInfo$1
@@ -499,12 +617,15 @@
android.content.pm.IPackageManager$Stub$Proxy
android.content.pm.InstrumentationInfo
android.content.pm.InstrumentationInfo$1
+android.content.pm.LauncherApps
android.content.pm.PackageInfo
android.content.pm.PackageInfo$1
android.content.pm.PackageItemInfo
android.content.pm.PackageManager
android.content.pm.PackageManager$NameNotFoundException
android.content.pm.PackageParser$PackageParserException
+android.content.pm.ParceledListSlice
+android.content.pm.ParceledListSlice$1
android.content.pm.PathPermission
android.content.pm.PathPermission$1
android.content.pm.PermissionInfo
@@ -530,14 +651,20 @@
android.content.res.CompatibilityInfo$2
android.content.res.Configuration
android.content.res.Configuration$1
+android.content.res.ConfigurationBoundResourceCache
+android.content.res.ConstantState
+android.content.res.DrawableCache
android.content.res.ObbInfo
android.content.res.ObbInfo$1
android.content.res.ObbScanner
android.content.res.Resources
android.content.res.Resources$NotFoundException
android.content.res.Resources$Theme
+android.content.res.Resources$ThemeKey
android.content.res.ResourcesKey
android.content.res.StringBlock
+android.content.res.StringBlock$StyleIDs
+android.content.res.ThemedResourceCache
android.content.res.TypedArray
android.content.res.XmlBlock
android.content.res.XmlBlock$Parser
@@ -619,9 +746,7 @@
android.graphics.AvoidXfermode
android.graphics.Bitmap
android.graphics.Bitmap$1
-android.graphics.Bitmap$2
android.graphics.Bitmap$BitmapFinalizer
-android.graphics.Bitmap$CompressFormat
android.graphics.Bitmap$Config
android.graphics.BitmapFactory
android.graphics.BitmapFactory$Options
@@ -709,13 +834,14 @@
android.graphics.Xfermode
android.graphics.YuvImage
android.graphics.drawable.Animatable
+android.graphics.drawable.Animatable2
android.graphics.drawable.AnimatedStateListDrawable
android.graphics.drawable.AnimatedStateListDrawable$AnimatedStateListState
-android.graphics.drawable.AnimatedStateListDrawable$AnimationDrawableTransition
-android.graphics.drawable.AnimatedStateListDrawable$FrameInterpolator
android.graphics.drawable.AnimatedStateListDrawable$Transition
android.graphics.drawable.AnimatedVectorDrawable
+android.graphics.drawable.AnimatedVectorDrawable$1
android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
+android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
android.graphics.drawable.AnimationDrawable
android.graphics.drawable.AnimationDrawable$AnimationState
android.graphics.drawable.BitmapDrawable
@@ -728,10 +854,13 @@
android.graphics.drawable.DrawableContainer
android.graphics.drawable.DrawableContainer$DrawableContainerState
android.graphics.drawable.DrawableContainer$DrawableContainerState$ConstantStateFuture
+android.graphics.drawable.DrawableWrapper
+android.graphics.drawable.DrawableWrapper$DrawableWrapperState
android.graphics.drawable.GradientDrawable
-android.graphics.drawable.GradientDrawable$1
android.graphics.drawable.GradientDrawable$GradientState
android.graphics.drawable.GradientDrawable$Orientation
+android.graphics.drawable.Icon
+android.graphics.drawable.Icon$1
android.graphics.drawable.InsetDrawable
android.graphics.drawable.InsetDrawable$InsetState
android.graphics.drawable.LayerDrawable
@@ -739,14 +868,19 @@
android.graphics.drawable.LayerDrawable$LayerState
android.graphics.drawable.NinePatchDrawable
android.graphics.drawable.NinePatchDrawable$NinePatchState
-android.graphics.drawable.Ripple
-android.graphics.drawable.Ripple$1
-android.graphics.drawable.Ripple$LogInterpolator
android.graphics.drawable.RippleBackground
android.graphics.drawable.RippleBackground$1
-android.graphics.drawable.RippleBackground$2
+android.graphics.drawable.RippleBackground$BackgroundProperty
+android.graphics.drawable.RippleComponent
+android.graphics.drawable.RippleComponent$RenderNodeAnimatorSet
android.graphics.drawable.RippleDrawable
android.graphics.drawable.RippleDrawable$RippleState
+android.graphics.drawable.RippleForeground
+android.graphics.drawable.RippleForeground$1
+android.graphics.drawable.RippleForeground$2
+android.graphics.drawable.RippleForeground$3
+android.graphics.drawable.RippleForeground$4
+android.graphics.drawable.RippleForeground$LogDecelerateInterpolator
android.graphics.drawable.RotateDrawable
android.graphics.drawable.RotateDrawable$RotateState
android.graphics.drawable.ScaleDrawable
@@ -763,6 +897,7 @@
android.graphics.drawable.VectorDrawable$VPath
android.graphics.drawable.VectorDrawable$VPathRenderer
android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.shapes.OvalShape
android.graphics.drawable.shapes.RectShape
android.graphics.drawable.shapes.Shape
android.graphics.pdf.PdfDocument
@@ -771,17 +906,15 @@
android.hardware.Camera
android.hardware.Camera$CameraInfo
android.hardware.Camera$Face
-android.hardware.Camera$Parameters
-android.hardware.Camera$PreviewCallback
+android.hardware.ConsumerIrManager
android.hardware.Sensor
android.hardware.SensorEventListener
android.hardware.SensorManager
+android.hardware.SerialManager
android.hardware.SerialPort
android.hardware.SystemSensorManager
android.hardware.SystemSensorManager$BaseEventQueue
-android.hardware.camera2.CameraCharacteristics
-android.hardware.camera2.CaptureRequest
-android.hardware.camera2.CaptureResult
+android.hardware.camera2.CameraManager
android.hardware.camera2.DngCreator
android.hardware.camera2.impl.CameraMetadataNative
android.hardware.camera2.legacy.LegacyCameraDevice
@@ -796,6 +929,8 @@
android.hardware.display.IDisplayManager$Stub$Proxy
android.hardware.display.IDisplayManagerCallback
android.hardware.display.IDisplayManagerCallback$Stub
+android.hardware.fingerprint.FingerprintManager
+android.hardware.hdmi.HdmiControlManager
android.hardware.input.IInputDevicesChangedListener
android.hardware.input.IInputDevicesChangedListener$Stub
android.hardware.input.IInputManager
@@ -805,6 +940,27 @@
android.hardware.input.InputDeviceIdentifier$1
android.hardware.input.InputManager
android.hardware.input.InputManager$InputDevicesChangedListener
+android.hardware.radio.RadioManager
+android.hardware.radio.RadioManager$AmBandConfig
+android.hardware.radio.RadioManager$AmBandConfig$1
+android.hardware.radio.RadioManager$AmBandDescriptor
+android.hardware.radio.RadioManager$AmBandDescriptor$1
+android.hardware.radio.RadioManager$BandConfig
+android.hardware.radio.RadioManager$BandConfig$1
+android.hardware.radio.RadioManager$BandDescriptor
+android.hardware.radio.RadioManager$BandDescriptor$1
+android.hardware.radio.RadioManager$FmBandConfig
+android.hardware.radio.RadioManager$FmBandConfig$1
+android.hardware.radio.RadioManager$FmBandDescriptor
+android.hardware.radio.RadioManager$FmBandDescriptor$1
+android.hardware.radio.RadioManager$ModuleProperties
+android.hardware.radio.RadioManager$ModuleProperties$1
+android.hardware.radio.RadioManager$ProgramInfo
+android.hardware.radio.RadioManager$ProgramInfo$1
+android.hardware.radio.RadioMetadata
+android.hardware.radio.RadioMetadata$1
+android.hardware.radio.RadioModule
+android.hardware.radio.RadioTuner
android.hardware.soundtrigger.SoundTrigger
android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel
android.hardware.soundtrigger.SoundTrigger$ConfidenceLevel$1
@@ -828,19 +984,220 @@
android.hardware.soundtrigger.SoundTriggerModule
android.hardware.usb.UsbDevice
android.hardware.usb.UsbDeviceConnection
+android.hardware.usb.UsbManager
android.hardware.usb.UsbRequest
-# Initializing android.icu.impl.ICUBinary loads the ICU data.
-# Opening the files in the Zygote avoids StrictMode violations.
-# It also ensures the ICU data files are mapped on boot and all
-# apps will be consistent (even if files are added to /data).
+android.icu.impl.BMPSet
+android.icu.impl.CacheBase
+android.icu.impl.CalendarData
+android.icu.impl.CalendarUtil
+android.icu.impl.ClassLoaderUtil
+android.icu.impl.CurrencyData
+android.icu.impl.CurrencyData$CurrencyDisplayInfo
+android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
+android.icu.impl.CurrencyData$CurrencySpacingInfo
+android.icu.impl.DateNumberFormat
+android.icu.impl.Grego
android.icu.impl.ICUBinary
+android.icu.impl.ICUBinary$Authenticate
+android.icu.impl.ICUBinary$DatPackageReader
+android.icu.impl.ICUBinary$DatPackageReader$IsAcceptable
+android.icu.impl.ICUBinary$DataFile
+android.icu.impl.ICUBinary$PackageDataFile
+android.icu.impl.ICUCache
+android.icu.impl.ICUConfig
+android.icu.impl.ICUCurrencyDisplayInfoProvider
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyMetaInfo
+android.icu.impl.ICUCurrencyMetaInfo$Collector
+android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
+android.icu.impl.ICUCurrencyMetaInfo$UniqueList
+android.icu.impl.ICUData
+android.icu.impl.ICUDebug
+android.icu.impl.ICUResourceBundle
+android.icu.impl.ICUResourceBundle$1
+android.icu.impl.ICUResourceBundle$OpenType
+android.icu.impl.ICUResourceBundle$WholeBundle
+android.icu.impl.ICUResourceBundleImpl
+android.icu.impl.ICUResourceBundleImpl$ResourceArray
+android.icu.impl.ICUResourceBundleImpl$ResourceBinary
+android.icu.impl.ICUResourceBundleImpl$ResourceContainer
+android.icu.impl.ICUResourceBundleImpl$ResourceInt
+android.icu.impl.ICUResourceBundleImpl$ResourceIntVector
+android.icu.impl.ICUResourceBundleImpl$ResourceString
+android.icu.impl.ICUResourceBundleImpl$ResourceTable
+android.icu.impl.ICUResourceBundleReader
+android.icu.impl.ICUResourceBundleReader$Array
+android.icu.impl.ICUResourceBundleReader$Array16
+android.icu.impl.ICUResourceBundleReader$Container
+android.icu.impl.ICUResourceBundleReader$IsAcceptable
+android.icu.impl.ICUResourceBundleReader$ReaderCache
+android.icu.impl.ICUResourceBundleReader$ReaderInfo
+android.icu.impl.ICUResourceBundleReader$ResourceCache
+android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
+android.icu.impl.ICUResourceBundleReader$Table
+android.icu.impl.ICUResourceBundleReader$Table16
+android.icu.impl.ICUResourceBundleReader$Table1632
+android.icu.impl.JavaTimeZone
+android.icu.impl.LocaleIDParser
+android.icu.impl.LocaleIDs
+android.icu.impl.OlsonTimeZone
+android.icu.impl.Pair
+android.icu.impl.PatternProps
+android.icu.impl.PatternTokenizer
+android.icu.impl.ReplaceableUCharacterIterator
+android.icu.impl.RuleCharacterIterator
+android.icu.impl.SimpleCache
+android.icu.impl.SoftCache
+android.icu.impl.SoftCache$SettableSoftReference
+android.icu.impl.Trie2
+android.icu.impl.Trie2$1
+android.icu.impl.Trie2$Range
+android.icu.impl.Trie2$Trie2Iterator
+android.icu.impl.Trie2$UTrie2Header
+android.icu.impl.Trie2$ValueMapper
+android.icu.impl.Trie2$ValueWidth
+android.icu.impl.Trie2_16
+android.icu.impl.UCharacterProperty
+android.icu.impl.UCharacterProperty$1
+android.icu.impl.UCharacterProperty$10
+android.icu.impl.UCharacterProperty$11
+android.icu.impl.UCharacterProperty$12
+android.icu.impl.UCharacterProperty$13
+android.icu.impl.UCharacterProperty$14
+android.icu.impl.UCharacterProperty$15
+android.icu.impl.UCharacterProperty$16
+android.icu.impl.UCharacterProperty$17
+android.icu.impl.UCharacterProperty$18
+android.icu.impl.UCharacterProperty$19
+android.icu.impl.UCharacterProperty$2
+android.icu.impl.UCharacterProperty$20
+android.icu.impl.UCharacterProperty$21
+android.icu.impl.UCharacterProperty$22
+android.icu.impl.UCharacterProperty$23
+android.icu.impl.UCharacterProperty$3
+android.icu.impl.UCharacterProperty$4
+android.icu.impl.UCharacterProperty$5
+android.icu.impl.UCharacterProperty$6
+android.icu.impl.UCharacterProperty$7
+android.icu.impl.UCharacterProperty$8
+android.icu.impl.UCharacterProperty$9
+android.icu.impl.UCharacterProperty$BiDiIntProperty
+android.icu.impl.UCharacterProperty$BinaryProperty
+android.icu.impl.UCharacterProperty$CaseBinaryProperty
+android.icu.impl.UCharacterProperty$CombiningClassIntProperty
+android.icu.impl.UCharacterProperty$IntProperty
+android.icu.impl.UCharacterProperty$IsAcceptable
+android.icu.impl.UCharacterProperty$NormInertBinaryProperty
+android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
+android.icu.impl.UPropertyAliases
+android.icu.impl.UPropertyAliases$IsAcceptable
+android.icu.impl.Utility
+android.icu.impl.ZoneMeta
+android.icu.impl.ZoneMeta$CustomTimeZoneCache
+android.icu.impl.ZoneMeta$SystemTimeZoneCache
+android.icu.impl.locale.AsciiUtil
+android.icu.impl.locale.BaseLocale
+android.icu.impl.locale.BaseLocale$Cache
+android.icu.impl.locale.BaseLocale$Key
+android.icu.impl.locale.LocaleObjectCache
+android.icu.impl.locale.LocaleObjectCache$CacheEntry
+android.icu.impl.locale.LocaleSyntaxException
+android.icu.lang.UCharacter
+android.icu.lang.UCharacterEnums$ECharacterCategory
+android.icu.lang.UCharacterEnums$ECharacterDirection
+android.icu.lang.UScript
+android.icu.lang.UScript$ScriptUsage
+android.icu.text.CurrencyDisplayNames
+android.icu.text.CurrencyMetaInfo
+android.icu.text.CurrencyMetaInfo$CurrencyDigits
+android.icu.text.CurrencyMetaInfo$CurrencyFilter
+android.icu.text.DateFormat
+android.icu.text.DateFormat$BooleanAttribute
+android.icu.text.DateFormat$Field
+android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$CapitalizationContextUsage
+android.icu.text.DateIntervalFormat
+android.icu.text.DateIntervalFormat$BestMatchInfo
+android.icu.text.DateIntervalInfo
+android.icu.text.DateIntervalInfo$PatternInfo
+android.icu.text.DateTimePatternGenerator
+android.icu.text.DateTimePatternGenerator$DTPGflags
+android.icu.text.DateTimePatternGenerator$DateTimeMatcher
+android.icu.text.DateTimePatternGenerator$DistanceInfo
+android.icu.text.DateTimePatternGenerator$FormatParser
+android.icu.text.DateTimePatternGenerator$PatternInfo
+android.icu.text.DateTimePatternGenerator$PatternWithMatcher
+android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
+android.icu.text.DateTimePatternGenerator$VariableField
+android.icu.text.DecimalFormat
+android.icu.text.DecimalFormatSymbols
+android.icu.text.DisplayContext
+android.icu.text.DisplayContext$Type
+android.icu.text.MessageFormat
+android.icu.text.MessageFormat$AppendableWrapper
+android.icu.text.MessageFormat$Field
+android.icu.text.MessagePattern
+android.icu.text.MessagePattern$ApostropheMode
+android.icu.text.MessagePattern$ArgType
+android.icu.text.MessagePattern$Part
+android.icu.text.MessagePattern$Part$Type
+android.icu.text.NumberFormat
+android.icu.text.NumberingSystem
+android.icu.text.Replaceable
+android.icu.text.ReplaceableString
+android.icu.text.SimpleDateFormat
+android.icu.text.SimpleDateFormat$PatternItem
+android.icu.text.UCharacterIterator
+android.icu.text.UFormat
+android.icu.text.UForwardCharacterIterator
+android.icu.text.UTF16
+android.icu.text.UnicodeFilter
+android.icu.text.UnicodeMatcher
+android.icu.text.UnicodeSet
+android.icu.text.UnicodeSet$Filter
+android.icu.text.UnicodeSet$GeneralCategoryMaskFilter
+android.icu.text.UnicodeSet$IntPropertyFilter
+android.icu.util.BasicTimeZone
+android.icu.util.BytesTrie
+android.icu.util.BytesTrie$Result
+android.icu.util.Calendar
+android.icu.util.Calendar$CalType
+android.icu.util.Calendar$FormatConfiguration
+android.icu.util.Calendar$PatternData
+android.icu.util.Calendar$WeekData
+android.icu.util.Calendar$WeekDataCache
+android.icu.util.Currency
+android.icu.util.Currency$EquivalenceRelation
+android.icu.util.Freezable
+android.icu.util.GregorianCalendar
+android.icu.util.MeasureUnit
+android.icu.util.MeasureUnit$1
+android.icu.util.MeasureUnit$2
+android.icu.util.MeasureUnit$3
+android.icu.util.MeasureUnit$Factory
+android.icu.util.SimpleTimeZone
+android.icu.util.TimeUnit
+android.icu.util.TimeZone
+android.icu.util.TimeZone$ConstantZone
+android.icu.util.ULocale
+android.icu.util.ULocale$Category
+android.icu.util.ULocale$JDKLocaleHelper
+android.icu.util.ULocale$Type
+android.icu.util.UResourceBundle
+android.icu.util.UResourceBundle$ResourceCacheKey
+android.icu.util.UResourceBundleIterator
+android.icu.util.UResourceTypeMismatchException
+android.icu.util.VersionInfo
android.inputmethodservice.ExtractEditText
+android.location.CountryDetector
android.location.Location
android.location.Location$1
+android.location.LocationManager
android.media.AmrInputStream
android.media.AudioAttributes
android.media.AudioAttributes$1
android.media.AudioAttributes$Builder
+android.media.AudioDeviceInfo
android.media.AudioDevicePort
android.media.AudioDevicePortConfig
android.media.AudioFormat
@@ -851,7 +1208,8 @@
android.media.AudioManager$1
android.media.AudioManager$FocusEventHandlerDelegate
android.media.AudioManager$FocusEventHandlerDelegate$1
-android.media.AudioManager$OnAudioFocusChangeListener
+android.media.AudioManager$OnAmPortUpdateListener
+android.media.AudioManager$OnAudioPortUpdateListener
android.media.AudioMixPort
android.media.AudioMixPortConfig
android.media.AudioPatch
@@ -876,33 +1234,46 @@
android.media.Image
android.media.ImageReader
android.media.ImageReader$SurfaceImage
+android.media.ImageWriter
+android.media.ImageWriter$WriterSurfaceImage
android.media.JetPlayer
android.media.MediaCodec
android.media.MediaCodecList
android.media.MediaCrypto
android.media.MediaDrm
android.media.MediaExtractor
-android.media.MediaFormat
android.media.MediaHTTPConnection
-android.media.MediaMetadata
android.media.MediaMetadataRetriever
android.media.MediaMuxer
android.media.MediaPlayer
-android.media.MediaPlayer$OnBufferingUpdateListener
+android.media.MediaPlayer$1
+android.media.MediaPlayer$EventHandler
android.media.MediaPlayer$OnCompletionListener
android.media.MediaPlayer$OnErrorListener
-android.media.MediaPlayer$OnPreparedListener
android.media.MediaPlayer$OnSeekCompleteListener
-android.media.MediaPlayer$OnVideoSizeChangedListener
+android.media.MediaPlayer$OnSubtitleDataListener
+android.media.MediaPlayer$TimeProvider
+android.media.MediaPlayer$TimeProvider$EventHandler
android.media.MediaRecorder
+android.media.MediaRouter
android.media.MediaScanner
+android.media.MediaSync
+android.media.MediaTimeProvider
+android.media.MediaTimeProvider$OnMediaTimeListener
+android.media.PlaybackParams
+android.media.PlaybackParams$1
android.media.RemoteDisplay
android.media.ResampleInputStream
-android.media.SoundPool$SoundPoolImpl
android.media.SubtitleController$Listener
+android.media.SyncParams
android.media.ToneGenerator
-android.media.audiofx.AudioEffect
-android.media.audiofx.LoudnessEnhancer
+android.media.audiopolicy.AudioMix
+android.media.audiopolicy.AudioMixingRule
+android.media.audiopolicy.AudioMixingRule$AttributeMatchCriterion
+android.media.midi.MidiManager
+android.media.projection.MediaProjectionManager
+android.media.session.MediaSessionManager
+android.media.tv.TvInputManager
android.mtp.MtpDatabase
android.mtp.MtpDevice
android.mtp.MtpDeviceInfo
@@ -916,9 +1287,16 @@
android.net.Credentials
android.net.DhcpResults
android.net.DhcpResults$1
+android.net.EthernetManager
android.net.IConnectivityManager
android.net.IConnectivityManager$Stub
android.net.IConnectivityManager$Stub$Proxy
+android.net.IpPrefix
+android.net.IpPrefix$1
+android.net.LinkAddress
+android.net.LinkAddress$1
+android.net.LinkProperties
+android.net.LinkProperties$1
android.net.LocalServerSocket
android.net.LocalSocket
android.net.LocalSocketImpl
@@ -928,11 +1306,16 @@
android.net.NetworkInfo$1
android.net.NetworkInfo$DetailedState
android.net.NetworkInfo$State
+android.net.NetworkPolicyManager
+android.net.NetworkScoreManager
android.net.NetworkStats
android.net.NetworkStats$1
android.net.NetworkUtils
android.net.Proxy
android.net.ProxyInfo
+android.net.ProxyInfo$1
+android.net.RouteInfo
+android.net.RouteInfo$1
android.net.SSLCertificateSocketFactory
android.net.SSLCertificateSocketFactory$1
android.net.SSLSessionCache
@@ -952,16 +1335,25 @@
android.net.Uri$PathSegments
android.net.Uri$PathSegmentsBuilder
android.net.Uri$StringUri
-android.net.WebAddress
android.net.http.AndroidHttpClient
android.net.http.AndroidHttpClient$1
-android.net.http.AndroidHttpClient$2
+android.net.nsd.NsdManager
android.net.wifi.IWifiManager
android.net.wifi.IWifiManager$Stub
android.net.wifi.IWifiManager$Stub$Proxy
+android.net.wifi.RttManager
+android.net.wifi.SupplicantState
+android.net.wifi.SupplicantState$1
android.net.wifi.WifiInfo
+android.net.wifi.WifiInfo$1
android.net.wifi.WifiManager
+android.net.wifi.WifiManager$ServiceHandler
android.net.wifi.WifiManager$WifiLock
+android.net.wifi.WifiScanner
+android.net.wifi.WifiSsid
+android.net.wifi.WifiSsid$1
+android.net.wifi.p2p.WifiP2pManager
+android.net.wifi.passpoint.WifiPasspointManager
android.nfc.IAppCallback
android.nfc.IAppCallback$Stub
android.nfc.INfcAdapter
@@ -973,11 +1365,9 @@
android.nfc.INfcTag
android.nfc.INfcTag$Stub
android.nfc.INfcTag$Stub$Proxy
-android.nfc.NdefRecord
android.nfc.NfcActivityManager
android.nfc.NfcAdapter
android.nfc.NfcAdapter$1
-android.nfc.NfcEvent
android.nfc.NfcManager
android.opengl.EGL14
android.opengl.EGLConfig
@@ -995,7 +1385,7 @@
android.opengl.GLES30
android.opengl.GLES31
android.opengl.GLES31Ext
-android.opengl.GLSurfaceView
+android.opengl.GLUtils
android.opengl.Matrix
android.opengl.Visibility
android.os.AsyncTask$1
@@ -1009,7 +1399,7 @@
android.os.AsyncTask$WorkerRunnable
android.os.BadParcelableException
android.os.BaseBundle
-android.os.BatteryStats
+android.os.BatteryManager
android.os.Binder
android.os.BinderProxy
android.os.Build
@@ -1019,7 +1409,6 @@
android.os.CancellationSignal
android.os.CancellationSignal$OnCancelListener
android.os.CancellationSignal$Transport
-android.os.ConditionVariable
android.os.DeadObjectException
android.os.Debug
android.os.Debug$MemoryInfo
@@ -1040,6 +1429,8 @@
android.os.IInterface
android.os.IMessenger
android.os.IMessenger$Stub
+android.os.IMessenger$Stub$Proxy
+android.os.INetworkManagementService
android.os.INetworkManagementService$Stub
android.os.INetworkManagementService$Stub$Proxy
android.os.IPowerManager
@@ -1065,8 +1456,12 @@
android.os.Parcelable
android.os.Parcelable$ClassLoaderCreator
android.os.Parcelable$Creator
+android.os.ParcelableParcel
+android.os.ParcelableParcel$1
android.os.PatternMatcher
android.os.PatternMatcher$1
+android.os.PersistableBundle
+android.os.PersistableBundle$1
android.os.PowerManager
android.os.PowerManager$WakeLock
android.os.PowerManager$WakeLock$1
@@ -1110,59 +1505,75 @@
android.os.UserHandle
android.os.UserHandle$1
android.os.UserManager
+android.os.Vibrator
android.os.ZygoteStartFailedEx
android.os.storage.IMountService
android.os.storage.IMountService$Stub
android.os.storage.IMountService$Stub$Proxy
+android.os.storage.StorageManager
android.os.storage.StorageVolume
android.os.storage.StorageVolume$1
-android.preference.ListPreference
android.preference.PreferenceActivity
android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
-android.preference.PreferenceFrameLayout
-android.preference.PreferenceGroup
android.preference.PreferenceManager
android.preference.PreferenceManager$OnPreferenceTreeClickListener
-android.preference.PreferenceScreen
+android.print.PrintManager
android.provider.BaseColumns
-android.provider.CallLog$Calls
android.provider.ContactsContract
+android.provider.ContactsContract$CommonDataKinds$BaseTypes
+android.provider.ContactsContract$CommonDataKinds$CommonColumns
+android.provider.ContactsContract$CommonDataKinds$Email
android.provider.ContactsContract$CommonDataKinds$Phone
android.provider.ContactsContract$ContactCounts
android.provider.ContactsContract$ContactNameColumns
android.provider.ContactsContract$ContactOptionsColumns
android.provider.ContactsContract$ContactStatusColumns
+android.provider.ContactsContract$Contacts
android.provider.ContactsContract$ContactsColumns
android.provider.ContactsContract$Data
android.provider.ContactsContract$DataColumns
android.provider.ContactsContract$DataColumnsWithJoins
android.provider.ContactsContract$DataUsageStatColumns
-android.provider.ContactsContract$PhoneLookup
android.provider.ContactsContract$RawContactsColumns
android.provider.ContactsContract$StatusColumns
-android.provider.DocumentsProvider
-android.provider.Downloads$Impl
-android.provider.SearchIndexablesContract
-android.provider.Settings
+android.provider.MediaStore$MediaColumns
android.provider.Settings$Global
android.provider.Settings$NameValueCache
android.provider.Settings$NameValueTable
android.provider.Settings$Secure
android.provider.Settings$SettingNotFoundException
android.provider.Settings$System
-android.provider.Telephony$Mms
-android.renderscript.RenderScript
+android.provider.Settings$System$1
+android.provider.Settings$System$2
+android.provider.Settings$System$3
+android.provider.Settings$System$4
+android.provider.Settings$System$5
+android.provider.Settings$System$6
+android.provider.Settings$System$7
+android.provider.Settings$System$8
+android.provider.Settings$System$9
+android.provider.Settings$System$DiscreteValueValidator
+android.provider.Settings$System$InclusiveFloatRangeValidator
+android.provider.Settings$System$InclusiveIntegerRangeValidator
+android.provider.Settings$System$Validator
+android.renderscript.RenderScriptCacheDir
+android.security.IKeystoreService
+android.security.IKeystoreService$Stub
+android.security.IKeystoreService$Stub$Proxy
+android.security.KeyStore
+android.security.KeyStoreException
+android.security.NetworkSecurityPolicy
android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
+android.security.keystore.AndroidKeyStoreKey
android.security.keystore.AndroidKeyStoreProvider
-android.speech.tts.TextToSpeechService
-android.speech.tts.TextToSpeechService$SpeechItemV1
-android.speech.tts.TextToSpeechService$SynthesisSpeechItemV1
-android.speech.tts.TextToSpeechService$SynthesisToFileOutputStreamSpeechItemV1
-android.speech.tts.TextToSpeechService$UtteranceSpeechItem
-android.speech.tts.TtsEngines
+android.security.keystore.KeyStoreCryptoOperation
+android.service.persistentdata.PersistentDataBlockManager
+android.system.ErrnoException
android.system.GaiException
+android.system.NetlinkSocketAddress
android.system.Os
android.system.OsConstants
+android.system.PacketSocketAddress
android.system.StructAddrinfo
android.system.StructFlock
android.system.StructGroupReq
@@ -1170,28 +1581,32 @@
android.system.StructLinger
android.system.StructPasswd
android.system.StructPollfd
+android.system.StructStat
android.system.StructStatVfs
android.system.StructTimeval
android.system.StructUcred
android.system.StructUtsname
-android.telecom.InCallService
+android.telecom.TelecomManager
+android.telephony.CarrierConfigManager
android.telephony.PhoneNumberUtils
android.telephony.Rlog
-android.telephony.SignalStrength
android.telephony.SubscriptionManager
android.telephony.TelephonyManager
android.text.AndroidBidi
android.text.AndroidCharacter
-android.text.BidiFormatter$DirectionalityEstimator
android.text.BoringLayout
android.text.BoringLayout$Metrics
+android.text.ClipboardManager
android.text.DynamicLayout
android.text.DynamicLayout$ChangeWatcher
android.text.Editable
android.text.Editable$Factory
android.text.GetChars
android.text.GraphicsOperations
+android.text.Html
android.text.Html$HtmlParser
+android.text.HtmlToSpannedConverter
+android.text.Hyphenator
android.text.InputFilter
android.text.InputType
android.text.Layout
@@ -1217,6 +1632,8 @@
android.text.Spanned
android.text.SpannedString
android.text.StaticLayout
+android.text.StaticLayout$Builder
+android.text.StaticLayout$LineBreaks
android.text.TextDirectionHeuristic
android.text.TextDirectionHeuristics
android.text.TextDirectionHeuristics$AnyStrong
@@ -1233,6 +1650,7 @@
android.text.TextUtils$TruncateAt
android.text.TextWatcher
android.text.format.DateFormat
+android.text.format.DateUtils
android.text.format.Time
android.text.format.Time$TimeCalculator
android.text.method.AllCapsTransformationMethod
@@ -1240,13 +1658,14 @@
android.text.method.BaseKeyListener
android.text.method.BaseMovementMethod
android.text.method.KeyListener
+android.text.method.LinkMovementMethod
android.text.method.MetaKeyKeyListener
android.text.method.MovementMethod
android.text.method.PasswordTransformationMethod
-android.text.method.QwertyKeyListener
android.text.method.ReplacementTransformationMethod
android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
+android.text.method.ScrollingMovementMethod
android.text.method.SingleLineTransformationMethod
android.text.method.TextKeyListener
android.text.method.TextKeyListener$Capitalize
@@ -1256,6 +1675,7 @@
android.text.style.CharacterStyle
android.text.style.ClickableSpan
android.text.style.EasyEditSpan
+android.text.style.ForegroundColorSpan
android.text.style.LeadingMarginSpan
android.text.style.LineBackgroundSpan
android.text.style.LineHeightSpan
@@ -1265,6 +1685,7 @@
android.text.style.SpellCheckSpan
android.text.style.StyleSpan
android.text.style.SuggestionSpan
+android.text.style.TabStopSpan
android.text.style.URLSpan
android.text.style.UpdateAppearance
android.text.style.UpdateLayout
@@ -1272,14 +1693,21 @@
android.transition.AutoTransition
android.transition.ChangeBounds
android.transition.ChangeBounds$1
+android.transition.ChangeBounds$2
+android.transition.ChangeBounds$3
+android.transition.ChangeBounds$4
+android.transition.ChangeBounds$5
+android.transition.ChangeBounds$6
android.transition.ChangeClipBounds
android.transition.ChangeImageTransform
android.transition.ChangeImageTransform$1
android.transition.ChangeImageTransform$2
android.transition.ChangeTransform
android.transition.ChangeTransform$1
+android.transition.ChangeTransform$2
android.transition.Fade
android.transition.PathMotion
+android.transition.Scene
android.transition.Transition
android.transition.Transition$1
android.transition.TransitionInflater
@@ -1301,7 +1729,6 @@
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
-android.util.FloatMath
android.util.FloatProperty
android.util.IntProperty
android.util.Log
@@ -1313,6 +1740,7 @@
android.util.MapCollections
android.util.MapCollections$ArrayIterator
android.util.MapCollections$KeySet
+android.util.MapCollections$ValuesCollection
android.util.MathUtils
android.util.MutableInt
android.util.MutableLong
@@ -1324,8 +1752,11 @@
android.util.Pools$Pool
android.util.Pools$SimplePool
android.util.Pools$SynchronizedPool
+android.util.Printer
android.util.Property
android.util.Singleton
+android.util.Size
+android.util.SizeF
android.util.Slog
android.util.SparseArray
android.util.SparseBooleanArray
@@ -1339,45 +1770,51 @@
android.view.AbsSavedState$2
android.view.ActionMode
android.view.ActionMode$Callback
+android.view.ActionProvider
android.view.ActionProvider$SubUiVisibilityListener
android.view.Choreographer
android.view.Choreographer$1
android.view.Choreographer$2
android.view.Choreographer$CallbackQueue
android.view.Choreographer$CallbackRecord
+android.view.Choreographer$FrameCallback
android.view.Choreographer$FrameDisplayEventReceiver
android.view.Choreographer$FrameHandler
android.view.ContextMenu
android.view.ContextMenu$ContextMenuInfo
android.view.ContextThemeWrapper
android.view.Display
+android.view.Display$Mode
+android.view.Display$Mode$1
android.view.DisplayAdjustments
android.view.DisplayEventReceiver
android.view.DisplayInfo
android.view.DisplayInfo$1
+android.view.DisplayListCanvas
android.view.FallbackEventHandler
android.view.FocusFinder
android.view.FocusFinder$1
android.view.FocusFinder$SequentialFocusComparator
+android.view.FrameInfo
android.view.FrameStats
-android.view.GLES20Canvas
-android.view.GLES20Canvas$CanvasFinalizer
-android.view.GLES20RecordingCanvas
android.view.GestureDetector
android.view.GestureDetector$GestureHandler
+android.view.GestureDetector$OnContextClickListener
android.view.GestureDetector$OnDoubleTapListener
android.view.GestureDetector$OnGestureListener
android.view.GestureDetector$SimpleOnGestureListener
android.view.GraphicBuffer
android.view.GraphicBuffer$1
android.view.Gravity
-android.view.HardwareCanvas
android.view.HardwareLayer
android.view.HardwareRenderer
android.view.HardwareRenderer$HardwareDrawCallbacks
android.view.IAssetAtlas
android.view.IAssetAtlas$Stub
android.view.IAssetAtlas$Stub$Proxy
+android.view.IGraphicsStats
+android.view.IGraphicsStats$Stub
+android.view.IGraphicsStats$Stub$Proxy
android.view.IRotationWatcher
android.view.IRotationWatcher$Stub
android.view.IWindow
@@ -1420,6 +1857,7 @@
android.view.MenuInflater$MenuState
android.view.MenuItem
android.view.MenuItem$OnActionExpandListener
+android.view.MenuItem$OnMenuItemClickListener
android.view.MotionEvent
android.view.MotionEvent$1
android.view.MotionEvent$PointerCoords
@@ -1429,6 +1867,7 @@
android.view.RenderNode
android.view.RenderNodeAnimator
android.view.RenderNodeAnimator$1
+android.view.SearchEvent
android.view.SubMenu
android.view.Surface
android.view.Surface$1
@@ -1439,18 +1878,17 @@
android.view.SurfaceHolder$Callback
android.view.SurfaceHolder$Callback2
android.view.SurfaceSession
-android.view.SurfaceView
android.view.TextureView
android.view.ThreadedRenderer
-android.view.ThreadedRenderer$AtlasInitializer
+android.view.ThreadedRenderer$ProcessInitializer
android.view.VelocityTracker
android.view.VelocityTracker$Estimator
android.view.View
+android.view.View$1
android.view.View$10
android.view.View$11
android.view.View$12
-android.view.View$13
-android.view.View$14
+android.view.View$2
android.view.View$3
android.view.View$4
android.view.View$5
@@ -1464,8 +1902,10 @@
android.view.View$BaseSavedState
android.view.View$BaseSavedState$1
android.view.View$CheckForTap
+android.view.View$ForegroundInfo
android.view.View$ListenerInfo
android.view.View$MeasureSpec
+android.view.View$OnApplyWindowInsetsListener
android.view.View$OnAttachStateChangeListener
android.view.View$OnClickListener
android.view.View$OnCreateContextMenuListener
@@ -1479,8 +1919,10 @@
android.view.View$TransformationInfo
android.view.View$UnsetPressedState
android.view.ViewConfiguration
+android.view.ViewDebug$HierarchyHandler
android.view.ViewGroup
-android.view.ViewGroup$3
+android.view.ViewGroup$1
+android.view.ViewGroup$2
android.view.ViewGroup$LayoutParams
android.view.ViewGroup$MarginLayoutParams
android.view.ViewGroup$OnHierarchyChangeListener
@@ -1490,8 +1932,12 @@
android.view.ViewOutlineProvider$1
android.view.ViewOutlineProvider$2
android.view.ViewOutlineProvider$3
-android.view.ViewOverlay$OverlayViewGroup
android.view.ViewParent
+android.view.ViewPropertyAnimator
+android.view.ViewPropertyAnimator$1
+android.view.ViewPropertyAnimator$AnimatorEventListener
+android.view.ViewPropertyAnimator$NameValuesHolder
+android.view.ViewPropertyAnimator$PropertyBundle
android.view.ViewRootImpl
android.view.ViewRootImpl$1
android.view.ViewRootImpl$4
@@ -1527,6 +1973,7 @@
android.view.ViewTreeObserver$CopyOnWriteArray
android.view.ViewTreeObserver$CopyOnWriteArray$Access
android.view.ViewTreeObserver$InternalInsetsInfo
+android.view.ViewTreeObserver$OnGlobalFocusChangeListener
android.view.ViewTreeObserver$OnGlobalLayoutListener
android.view.ViewTreeObserver$OnPreDrawListener
android.view.ViewTreeObserver$OnScrollChangedListener
@@ -1535,6 +1982,8 @@
android.view.Window$Callback
android.view.Window$OnWindowDismissedCallback
android.view.WindowAnimationFrameStats
+android.view.WindowAnimationFrameStats$1
+android.view.WindowContentFrameStats
android.view.WindowContentFrameStats$1
android.view.WindowInsets
android.view.WindowLeaked
@@ -1546,6 +1995,7 @@
android.view.WindowManagerGlobal$2
android.view.WindowManagerImpl
android.view.accessibility.AccessibilityEvent
+android.view.accessibility.AccessibilityEventSource
android.view.accessibility.AccessibilityManager
android.view.accessibility.AccessibilityManager$1
android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
@@ -1554,6 +2004,7 @@
android.view.accessibility.AccessibilityNodeInfo
android.view.accessibility.AccessibilityNodeProvider
android.view.accessibility.AccessibilityRecord
+android.view.accessibility.CaptioningManager
android.view.accessibility.IAccessibilityManager
android.view.accessibility.IAccessibilityManager$Stub
android.view.accessibility.IAccessibilityManager$Stub$Proxy
@@ -1561,14 +2012,20 @@
android.view.accessibility.IAccessibilityManagerClient$Stub
android.view.animation.AccelerateDecelerateInterpolator
android.view.animation.AccelerateInterpolator
+android.view.animation.AlphaAnimation
android.view.animation.Animation
+android.view.animation.Animation$1
+android.view.animation.Animation$2
+android.view.animation.Animation$3
android.view.animation.Animation$AnimationListener
android.view.animation.AnimationUtils
+android.view.animation.BaseInterpolator
android.view.animation.DecelerateInterpolator
android.view.animation.Interpolator
android.view.animation.LinearInterpolator
android.view.animation.PathInterpolator
android.view.animation.Transformation
+android.view.animation.TranslateAnimation
android.view.inputmethod.BaseInputConnection
android.view.inputmethod.ComposingText
android.view.inputmethod.CursorAnchorInfo
@@ -1586,24 +2043,39 @@
android.view.inputmethod.InputMethodManager$H
android.view.inputmethod.InputMethodManager$ImeInputEventSender
android.view.inputmethod.InputMethodManager$PendingEvent
+android.view.textservice.SpellCheckerSession$SpellCheckerSessionListener
+android.view.textservice.SpellCheckerSubtype
+android.view.textservice.SpellCheckerSubtype$1
+android.view.textservice.TextServicesManager
+android.webkit.IWebViewUpdateService
+android.webkit.IWebViewUpdateService$Stub
+android.webkit.WebView
android.webkit.WebViewFactory
+android.webkit.WebViewFactory$MissingWebViewPackageException
android.widget.AbsListView
+android.widget.AbsListView$3
android.widget.AbsListView$AdapterDataSetObserver
android.widget.AbsListView$CheckForTap
android.widget.AbsListView$LayoutParams
android.widget.AbsListView$OnScrollListener
+android.widget.AbsListView$PerformClick
android.widget.AbsListView$RecycleBin
android.widget.AbsListView$SavedState
android.widget.AbsListView$SavedState$1
-android.widget.AbsSeekBar
+android.widget.AbsListView$SelectionBoundsAdjuster
+android.widget.AbsListView$WindowRunnnable
android.widget.AbsSpinner
+android.widget.AbsSpinner$RecycleBin
android.widget.AbsoluteLayout
android.widget.ActionMenuPresenter
+android.widget.ActionMenuPresenter$1
+android.widget.ActionMenuPresenter$2
android.widget.ActionMenuPresenter$OverflowMenuButton
android.widget.ActionMenuPresenter$OverflowMenuButton$1
android.widget.ActionMenuPresenter$PopupPresenterCallback
android.widget.ActionMenuView
android.widget.ActionMenuView$ActionMenuChildView
+android.widget.ActionMenuView$LayoutParams
android.widget.ActionMenuView$OnMenuItemClickListener
android.widget.Adapter
android.widget.AdapterView
@@ -1611,46 +2083,41 @@
android.widget.AdapterView$OnItemClickListener
android.widget.AdapterView$OnItemSelectedListener
android.widget.ArrayAdapter
-android.widget.AutoCompleteTextView
android.widget.BaseAdapter
android.widget.Button
-android.widget.CheckBox
android.widget.Checkable
-android.widget.CheckedTextView
android.widget.CompoundButton
android.widget.CompoundButton$OnCheckedChangeListener
-android.widget.DatePicker
android.widget.EdgeEffect
android.widget.EditText
android.widget.Editor
+android.widget.Editor$1
+android.widget.Editor$2
+android.widget.Editor$Blink
android.widget.Editor$CursorAnchorInfoNotifier
-android.widget.Editor$HandleView
+android.widget.Editor$EditOperation
+android.widget.Editor$EditOperation$1
android.widget.Editor$InputContentType
android.widget.Editor$InputMethodState
-android.widget.Editor$InsertionHandleView
android.widget.Editor$PositionListener
android.widget.Editor$SpanController
-android.widget.Editor$TextDisplayList
+android.widget.Editor$TextRenderNode
android.widget.Editor$TextViewPositionListener
-android.widget.FastScroller
+android.widget.Editor$UndoInputFilter
android.widget.Filter
android.widget.Filter$FilterListener
android.widget.Filterable
android.widget.FrameLayout
android.widget.FrameLayout$LayoutParams
-android.widget.GridLayout
-android.widget.GridView
android.widget.HeaderViewListAdapter
android.widget.HorizontalScrollView
android.widget.ImageButton
-android.widget.ImageSwitcher
android.widget.ImageView
android.widget.ImageView$ScaleType
android.widget.LinearLayout
android.widget.LinearLayout$LayoutParams
android.widget.ListAdapter
android.widget.ListPopupWindow
-android.widget.ListPopupWindow$DropDownListView
android.widget.ListPopupWindow$ForwardingListener
android.widget.ListPopupWindow$ListSelectorHider
android.widget.ListPopupWindow$PopupDataSetObserver
@@ -1659,25 +2126,22 @@
android.widget.ListPopupWindow$ResizePopupRunnable
android.widget.ListView
android.widget.ListView$ArrowScrollFocusResult
-android.widget.MediaController
-android.widget.MultiAutoCompleteTextView
+android.widget.ListView$FixedViewInfo
android.widget.OverScroller
android.widget.OverScroller$SplineOverScroller
android.widget.PopupWindow
android.widget.PopupWindow$1
-android.widget.PopupWindow$PopupViewContainer
+android.widget.PopupWindow$OnDismissListener
android.widget.ProgressBar
android.widget.ProgressBar$SavedState
android.widget.ProgressBar$SavedState$1
-android.widget.QuickContactBadge
-android.widget.RatingBar
android.widget.RelativeLayout
android.widget.RelativeLayout$DependencyGraph
android.widget.RelativeLayout$DependencyGraph$Node
android.widget.RelativeLayout$LayoutParams
android.widget.RemoteViews
android.widget.RemoteViews$1
-android.widget.RemoteViews$3
+android.widget.RemoteViews$2
android.widget.RemoteViews$Action
android.widget.RemoteViews$ActionException
android.widget.RemoteViews$BitmapCache
@@ -1687,20 +2151,25 @@
android.widget.RemoteViews$ReflectionAction
android.widget.RemoteViews$SetDrawableParameters
android.widget.RemoteViews$TextViewSizeAction
+android.widget.RemoteViews$ViewPaddingAction
android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
android.widget.RtlSpacingHelper
android.widget.ScrollBarDrawable
android.widget.ScrollView
+android.widget.ScrollView$SavedState
+android.widget.ScrollView$SavedState$1
android.widget.Scroller
android.widget.Scroller$ViscousFluidInterpolator
android.widget.SectionIndexer
-android.widget.SeekBar
-android.widget.SimpleCursorAdapter
+android.widget.Space
+android.widget.SpellChecker
+android.widget.SpellChecker$SpellParser
+android.widget.Spinner
+android.widget.Spinner$SpinnerPopup
android.widget.SpinnerAdapter
-android.widget.Switch
-android.widget.TableLayout
android.widget.TextView
-android.widget.TextView$4
+android.widget.TextView$2
+android.widget.TextView$3
android.widget.TextView$BufferType
android.widget.TextView$ChangeWatcher
android.widget.TextView$CharWrapper
@@ -1708,37 +2177,63 @@
android.widget.TextView$OnEditorActionListener
android.widget.TextView$SavedState
android.widget.TextView$SavedState$1
-android.widget.TimePicker
-android.widget.ToggleButton
+android.widget.ThemedSpinnerAdapter
android.widget.Toolbar
android.widget.Toolbar$1
android.widget.Toolbar$2
android.widget.Toolbar$ExpandedActionViewMenuPresenter
android.widget.Toolbar$LayoutParams
-android.widget.ViewAnimator
-android.widget.ViewFlipper
-android.widget.ViewSwitcher
android.widget.WrapperListAdapter
com.android.dex.Annotation
+com.android.dex.ClassData
+com.android.dex.ClassData$Method
+com.android.dex.ClassDef
+com.android.dex.Code
+com.android.dex.Dex
+com.android.dex.Dex$ClassDefIterable
+com.android.dex.Dex$FieldIdTable
+com.android.dex.Dex$MethodIdTable
+com.android.dex.Dex$ProtoIdTable
+com.android.dex.Dex$Section
+com.android.dex.Dex$StringTable
+com.android.dex.Dex$TypeIndexToDescriptorIndexTable
+com.android.dex.Dex$TypeIndexToDescriptorTable
+com.android.dex.DexException
com.android.dex.DexFormat
com.android.dex.EncodedValue
com.android.dex.EncodedValueCodec
com.android.dex.EncodedValueReader
+com.android.dex.FieldId
com.android.dex.Leb128
+com.android.dex.MethodId
com.android.dex.Mutf8
+com.android.dex.TableOfContents
+com.android.dex.TableOfContents$Section
+com.android.dex.TypeList
com.android.dex.util.ByteArrayByteInput
-com.android.i18n.phonenumbers.AsYouTypeFormatter
-com.android.i18n.phonenumbers.PhoneNumberMatcher
+com.android.dex.util.ByteInput
+com.android.dex.util.ByteOutput
+com.android.dex.util.ExceptionWithContext
+com.android.dex.util.FileUtils
+com.android.i18n.phonenumbers.CountryCodeToRegionCodeMap
+com.android.i18n.phonenumbers.MetadataLoader
+com.android.i18n.phonenumbers.NumberParseException
com.android.i18n.phonenumbers.PhoneNumberUtil
-com.android.i18n.phonenumbers.Phonemetadata$PhoneMetadata
+com.android.i18n.phonenumbers.PhoneNumberUtil$1
+com.android.i18n.phonenumbers.RegexCache
+com.android.i18n.phonenumbers.RegexCache$LRUCache
+com.android.i18n.phonenumbers.RegexCache$LRUCache$1
com.android.internal.R$styleable
+com.android.internal.app.AlertController
+com.android.internal.app.AlertController$1
+com.android.internal.app.AlertController$2
+com.android.internal.app.AlertController$AlertParams
+com.android.internal.app.AlertController$ButtonHandler
com.android.internal.app.IAppOpsService
com.android.internal.app.IAppOpsService$Stub
com.android.internal.app.IAppOpsService$Stub$Proxy
-com.android.internal.app.IBatteryStats$Stub
com.android.internal.app.IVoiceInteractor
com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.app.ResolverActivity$ResolveListAdapter
com.android.internal.app.WindowDecorActionBar
com.android.internal.app.WindowDecorActionBar$1
com.android.internal.app.WindowDecorActionBar$2
@@ -1747,18 +2242,15 @@
com.android.internal.appwidget.IAppWidgetService$Stub
com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
com.android.internal.content.NativeLibraryHelper
+com.android.internal.content.ReferrerIntent
+com.android.internal.content.ReferrerIntent$1
com.android.internal.logging.AndroidConfig
com.android.internal.logging.AndroidHandler
com.android.internal.logging.AndroidHandler$1
com.android.internal.net.NetworkStatsFactory
com.android.internal.os.AndroidPrintStream
-com.android.internal.os.BatteryStatsImpl
-com.android.internal.os.BatteryStatsImpl$Uid
com.android.internal.os.BinderInternal
com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.IDropBoxManagerService
-com.android.internal.os.IDropBoxManagerService$Stub
-com.android.internal.os.IDropBoxManagerService$Stub$Proxy
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
com.android.internal.os.RuntimeInit
@@ -1773,21 +2265,19 @@
com.android.internal.os.ZygoteInit
com.android.internal.os.ZygoteInit$MethodAndArgsCaller
com.android.internal.os.ZygoteSecurityException
-com.android.internal.policy.IPolicy
-com.android.internal.policy.PolicyManager
-com.android.internal.policy.impl.PhoneFallbackEventHandler
-com.android.internal.policy.impl.PhoneLayoutInflater
-com.android.internal.policy.impl.PhoneWindow
-com.android.internal.policy.impl.PhoneWindow$1
-com.android.internal.policy.impl.PhoneWindow$ActionMenuPresenterCallback
-com.android.internal.policy.impl.PhoneWindow$DecorView
-com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback
-com.android.internal.policy.impl.PhoneWindow$PanelFeatureState
-com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
-com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState$1
-com.android.internal.policy.impl.PhoneWindow$RotationWatcher
-com.android.internal.policy.impl.PhoneWindow$RotationWatcher$1
-com.android.internal.policy.impl.Policy
+com.android.internal.policy.PhoneFallbackEventHandler
+com.android.internal.policy.PhoneLayoutInflater
+com.android.internal.policy.PhoneWindow
+com.android.internal.policy.PhoneWindow$1
+com.android.internal.policy.PhoneWindow$ActionMenuPresenterCallback
+com.android.internal.policy.PhoneWindow$ColorViewState
+com.android.internal.policy.PhoneWindow$DecorView
+com.android.internal.policy.PhoneWindow$DialogMenuCallback
+com.android.internal.policy.PhoneWindow$PanelFeatureState
+com.android.internal.policy.PhoneWindow$PanelFeatureState$SavedState
+com.android.internal.policy.PhoneWindow$PanelFeatureState$SavedState$1
+com.android.internal.policy.PhoneWindow$RotationWatcher
+com.android.internal.policy.PhoneWindow$RotationWatcher$1
com.android.internal.telephony.ISub
com.android.internal.telephony.ISub$Stub
com.android.internal.telephony.ISub$Stub$Proxy
@@ -1798,14 +2288,23 @@
com.android.internal.telephony.ITelephonyRegistry$Stub
com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
com.android.internal.telephony.PhoneConstants$State
+com.android.internal.textservice.ITextServicesManager
+com.android.internal.textservice.ITextServicesManager$Stub
+com.android.internal.textservice.ITextServicesManager$Stub$Proxy
+com.android.internal.transition.EpicenterTranslateClipReveal
+com.android.internal.transition.TransitionConstants
com.android.internal.util.ArrayUtils
+com.android.internal.util.AsyncChannel
+com.android.internal.util.AsyncChannel$DeathMonitor
+com.android.internal.util.FastMath
com.android.internal.util.FastPrintWriter
-com.android.internal.util.FastPrintWriter$1
+com.android.internal.util.FastPrintWriter$DummyWriter
com.android.internal.util.FastXmlSerializer
com.android.internal.util.GrowingArrayUtils
com.android.internal.util.Preconditions
com.android.internal.util.VirtualRefBasePtr
com.android.internal.util.XmlUtils
+com.android.internal.util.XmlUtils$WriteMapCallback
com.android.internal.view.ActionBarPolicy
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputConnectionWrapper$MyHandler
@@ -1853,88 +2352,104 @@
com.android.internal.widget.ActionBarOverlayLayout$ActionBarVisibilityCallback
com.android.internal.widget.ActionBarOverlayLayout$LayoutParams
com.android.internal.widget.BackgroundFallback
+com.android.internal.widget.ButtonBarLayout
com.android.internal.widget.DecorContentParent
com.android.internal.widget.DecorToolbar
+com.android.internal.widget.DialogTitle
com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.LockPatternUtils
-com.android.internal.widget.ScrollingTabContainerView
-com.android.internal.widget.ScrollingTabContainerView$TabView
com.android.internal.widget.ToolbarWidgetWrapper
com.android.internal.widget.ToolbarWidgetWrapper$1
com.android.okhttp.Address
+com.android.okhttp.Authenticator
com.android.okhttp.CacheControl
+com.android.okhttp.CacheControl$Builder
+com.android.okhttp.CertificatePinner
+com.android.okhttp.CertificatePinner$Builder
+com.android.okhttp.CipherSuite
com.android.okhttp.ConfigAwareConnectionPool
com.android.okhttp.ConfigAwareConnectionPool$1
com.android.okhttp.Connection
com.android.okhttp.ConnectionPool
com.android.okhttp.ConnectionPool$1
+com.android.okhttp.ConnectionSpec
+com.android.okhttp.ConnectionSpec$Builder
com.android.okhttp.Dispatcher
com.android.okhttp.Handshake
com.android.okhttp.Headers
com.android.okhttp.Headers$Builder
-com.android.okhttp.HostResolver
-com.android.okhttp.HostResolver$1
com.android.okhttp.HttpHandler
com.android.okhttp.HttpsHandler
-com.android.okhttp.OkAuthenticator
com.android.okhttp.OkHttpClient
-com.android.okhttp.OkResponseCache
+com.android.okhttp.OkHttpClient$1
+com.android.okhttp.OkUrlFactory
com.android.okhttp.Protocol
com.android.okhttp.Request
com.android.okhttp.Request$Builder
-com.android.okhttp.Request$ParsedHeaders
+com.android.okhttp.RequestBody
+com.android.okhttp.RequestBody$2
com.android.okhttp.Response
-com.android.okhttp.Response$Body
com.android.okhttp.Response$Builder
-com.android.okhttp.ResponseSource
+com.android.okhttp.ResponseBody
com.android.okhttp.Route
-com.android.okhttp.RouteDatabase
-com.android.okhttp.TunnelRequest
+com.android.okhttp.TlsVersion
+com.android.okhttp.internal.ConnectionSpecSelector
+com.android.okhttp.internal.Internal
+com.android.okhttp.internal.Network
+com.android.okhttp.internal.Network$1
+com.android.okhttp.internal.OptionalMethod
com.android.okhttp.internal.Platform
+com.android.okhttp.internal.RouteDatabase
com.android.okhttp.internal.Util
com.android.okhttp.internal.Util$1
+com.android.okhttp.internal.http.AuthenticatorAdapter
com.android.okhttp.internal.http.CacheStrategy
-com.android.okhttp.internal.http.CacheStrategy$1
com.android.okhttp.internal.http.CacheStrategy$Factory
-com.android.okhttp.internal.http.DelegatingHttpsURLConnection
-com.android.okhttp.internal.http.HttpAuthenticator
-com.android.okhttp.internal.http.HttpAuthenticator$1
com.android.okhttp.internal.http.HttpConnection
com.android.okhttp.internal.http.HttpConnection$AbstractSource
com.android.okhttp.internal.http.HttpConnection$ChunkedSource
com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
com.android.okhttp.internal.http.HttpEngine
+com.android.okhttp.internal.http.HttpEngine$1
com.android.okhttp.internal.http.HttpMethod
com.android.okhttp.internal.http.HttpTransport
-com.android.okhttp.internal.http.HttpURLConnectionImpl
-com.android.okhttp.internal.http.HttpURLConnectionImpl$Retry
-com.android.okhttp.internal.http.HttpsURLConnectionImpl
com.android.okhttp.internal.http.OkHeaders
com.android.okhttp.internal.http.OkHeaders$1
+com.android.okhttp.internal.http.RealResponseBody
+com.android.okhttp.internal.http.RequestException
com.android.okhttp.internal.http.RequestLine
com.android.okhttp.internal.http.RetryableSink
+com.android.okhttp.internal.http.RouteException
com.android.okhttp.internal.http.RouteSelector
+com.android.okhttp.internal.http.SocketConnector
+com.android.okhttp.internal.http.SocketConnector$ConnectedSocket
com.android.okhttp.internal.http.StatusLine
com.android.okhttp.internal.http.Transport
+com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
+com.android.okhttp.internal.huc.HttpURLConnectionImpl
+com.android.okhttp.internal.huc.HttpsURLConnectionImpl
com.android.okhttp.internal.tls.OkHostnameVerifier
-com.android.okio.BufferedSink
-com.android.okio.BufferedSource
-com.android.okio.ByteString
-com.android.okio.Deadline
-com.android.okio.Deadline$1
-com.android.okio.OkBuffer
-com.android.okio.Okio
-com.android.okio.Okio$1
-com.android.okio.Okio$2
-com.android.okio.RealBufferedSink
-com.android.okio.RealBufferedSink$1
-com.android.okio.RealBufferedSource
-com.android.okio.RealBufferedSource$1
-com.android.okio.Segment
-com.android.okio.SegmentPool
-com.android.okio.Sink
-com.android.okio.Source
-com.android.okio.Util
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.okio.AsyncTimeout$1
+com.android.okhttp.okio.AsyncTimeout$2
+com.android.okhttp.okio.AsyncTimeout$Watchdog
+com.android.okhttp.okio.Buffer
+com.android.okhttp.okio.BufferedSink
+com.android.okhttp.okio.BufferedSource
+com.android.okhttp.okio.Okio
+com.android.okhttp.okio.Okio$1
+com.android.okhttp.okio.Okio$2
+com.android.okhttp.okio.Okio$3
+com.android.okhttp.okio.RealBufferedSink
+com.android.okhttp.okio.RealBufferedSink$1
+com.android.okhttp.okio.RealBufferedSource
+com.android.okhttp.okio.RealBufferedSource$1
+com.android.okhttp.okio.Segment
+com.android.okhttp.okio.SegmentPool
+com.android.okhttp.okio.Sink
+com.android.okhttp.okio.Source
+com.android.okhttp.okio.Timeout
+com.android.okhttp.okio.Timeout$1
+com.android.okhttp.okio.Util
com.android.org.bouncycastle.asn1.ASN1Boolean
com.android.org.bouncycastle.asn1.ASN1Choice
com.android.org.bouncycastle.asn1.ASN1Encodable
@@ -1946,8 +2461,10 @@
com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
com.android.org.bouncycastle.asn1.ASN1OctetString
com.android.org.bouncycastle.asn1.ASN1OctetStringParser
+com.android.org.bouncycastle.asn1.ASN1OutputStream
com.android.org.bouncycastle.asn1.ASN1Primitive
com.android.org.bouncycastle.asn1.ASN1Sequence
+com.android.org.bouncycastle.asn1.ASN1SequenceParser
com.android.org.bouncycastle.asn1.ASN1Set
com.android.org.bouncycastle.asn1.ASN1StreamParser
com.android.org.bouncycastle.asn1.ASN1String
@@ -1955,19 +2472,16 @@
com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
com.android.org.bouncycastle.asn1.BERTags
com.android.org.bouncycastle.asn1.DERBitString
-com.android.org.bouncycastle.asn1.DERBoolean
com.android.org.bouncycastle.asn1.DERFactory
com.android.org.bouncycastle.asn1.DERIA5String
-com.android.org.bouncycastle.asn1.DERInteger
com.android.org.bouncycastle.asn1.DERNull
-com.android.org.bouncycastle.asn1.DERObjectIdentifier
com.android.org.bouncycastle.asn1.DEROctetString
+com.android.org.bouncycastle.asn1.DEROutputStream
com.android.org.bouncycastle.asn1.DERPrintableString
com.android.org.bouncycastle.asn1.DERSequence
com.android.org.bouncycastle.asn1.DERSet
com.android.org.bouncycastle.asn1.DERTaggedObject
com.android.org.bouncycastle.asn1.DERUTF8String
-com.android.org.bouncycastle.asn1.DERUniversalString
com.android.org.bouncycastle.asn1.DLSequence
com.android.org.bouncycastle.asn1.DLSet
com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
@@ -1980,6 +2494,12 @@
com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+com.android.org.bouncycastle.asn1.x500.AttributeTypeAndValue
+com.android.org.bouncycastle.asn1.x500.RDN
+com.android.org.bouncycastle.asn1.x500.X500Name
+com.android.org.bouncycastle.asn1.x500.X500NameStyle
+com.android.org.bouncycastle.asn1.x500.style.AbstractX500NameStyle
+com.android.org.bouncycastle.asn1.x500.style.BCStyle
com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
com.android.org.bouncycastle.asn1.x509.BasicConstraints
com.android.org.bouncycastle.asn1.x509.Extension
@@ -1988,8 +2508,6 @@
com.android.org.bouncycastle.asn1.x509.PolicyInformation
com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
com.android.org.bouncycastle.asn1.x509.X509Extension
-com.android.org.bouncycastle.asn1.x509.X509Extensions
-com.android.org.bouncycastle.asn1.x509.X509Name
com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
com.android.org.bouncycastle.crypto.Digest
@@ -1999,6 +2517,8 @@
com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
+com.android.org.bouncycastle.jcajce.PKIXExtendedParameters
+com.android.org.bouncycastle.jcajce.PKIXExtendedParameters$Builder
com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
@@ -2032,7 +2552,6 @@
com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
com.android.org.bouncycastle.jcajce.provider.symmetric.AES
-com.android.org.bouncycastle.jcajce.provider.symmetric.AES$ECB
com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4$Mappings
@@ -2052,6 +2571,9 @@
com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
+com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
+com.android.org.bouncycastle.jcajce.util.JcaJceHelper
+com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
com.android.org.bouncycastle.jce.exception.ExtException
com.android.org.bouncycastle.jce.interfaces.BCKeyStore
com.android.org.bouncycastle.jce.provider.AnnotatedException
@@ -2065,8 +2587,10 @@
com.android.org.bouncycastle.jce.provider.PKIXNameConstraintValidator
com.android.org.bouncycastle.jce.provider.PKIXNameConstraintValidatorException
com.android.org.bouncycastle.jce.provider.PKIXPolicyNode
+com.android.org.bouncycastle.jce.provider.PrincipalUtils
com.android.org.bouncycastle.jce.provider.RFC3280CertPathUtilities
com.android.org.bouncycastle.util.Arrays
+com.android.org.bouncycastle.util.Encodable
com.android.org.bouncycastle.util.Strings
com.android.org.bouncycastle.util.encoders.Encoder
com.android.org.bouncycastle.util.encoders.Hex
@@ -2075,6 +2599,7 @@
com.android.org.bouncycastle.x509.ExtendedPKIXParameters
com.android.org.conscrypt.AbstractSessionContext
com.android.org.conscrypt.AbstractSessionContext$1
+com.android.org.conscrypt.AddressUtils
com.android.org.conscrypt.ByteArray
com.android.org.conscrypt.CertPinManager
com.android.org.conscrypt.ChainStrengthAnalyzer
@@ -2088,17 +2613,23 @@
com.android.org.conscrypt.KeyManagerImpl
com.android.org.conscrypt.NativeCrypto
com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
+com.android.org.conscrypt.NativeCryptoJni
+com.android.org.conscrypt.NativeRef
+com.android.org.conscrypt.NativeRef$EC_GROUP
+com.android.org.conscrypt.NativeRef$EC_POINT
+com.android.org.conscrypt.NativeRef$EVP_MD_CTX
+com.android.org.conscrypt.NativeRef$EVP_PKEY
com.android.org.conscrypt.OpenSSLBIOInputStream
-com.android.org.conscrypt.OpenSSLCipher$AES$CBC$PKCS5Padding
com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.OpenSSLDigestContext
+com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
+com.android.org.conscrypt.OpenSSLECGroupContext
+com.android.org.conscrypt.OpenSSLECPointContext
+com.android.org.conscrypt.OpenSSLECPublicKey
com.android.org.conscrypt.OpenSSLKey
com.android.org.conscrypt.OpenSSLKeyHolder
com.android.org.conscrypt.OpenSSLMessageDigestJDK
com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
-com.android.org.conscrypt.OpenSSLNativeReference
com.android.org.conscrypt.OpenSSLProvider
com.android.org.conscrypt.OpenSSLRSAPublicKey
com.android.org.conscrypt.OpenSSLRandom
@@ -2117,7 +2648,6 @@
com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
com.android.org.conscrypt.PinEntryException
-com.android.org.conscrypt.PinListEntry
com.android.org.conscrypt.PinManagerException
com.android.org.conscrypt.Platform
com.android.org.conscrypt.Platform$OpenSSLMapper
@@ -2135,7 +2665,7 @@
com.android.org.conscrypt.TrustedCertificateStore$1
com.android.org.conscrypt.TrustedCertificateStore$2
com.android.org.conscrypt.TrustedCertificateStore$CertSelector
-com.android.org.conscrypt.util.Arrays
+com.android.org.conscrypt.util.ArrayUtils
com.android.server.NetworkManagementSocketTagger
com.android.server.NetworkManagementSocketTagger$1
com.android.server.NetworkManagementSocketTagger$SocketTags
@@ -2143,17 +2673,27 @@
com.google.android.collect.Maps
com.google.android.gles_jni.EGLImpl
com.google.android.gles_jni.GLImpl
+dalvik.system.BaseDexClassLoader
dalvik.system.BlockGuard
dalvik.system.BlockGuard$1
dalvik.system.BlockGuard$2
dalvik.system.BlockGuard$BlockGuardPolicyException
dalvik.system.BlockGuard$Policy
+dalvik.system.CloseGuard
+dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$Reporter
dalvik.system.DalvikLogHandler
dalvik.system.DalvikLogging
+dalvik.system.DexFile
+dalvik.system.DexFile$DFEnum
+dalvik.system.DexPathList
+dalvik.system.DexPathList$Element
+dalvik.system.PathClassLoader
dalvik.system.SocketTagger
dalvik.system.SocketTagger$1
dalvik.system.VMDebug
dalvik.system.VMRuntime
+dalvik.system.VMStack
dalvik.system.ZygoteHooks
java.beans.PropertyChangeEvent
java.beans.PropertyChangeSupport
@@ -2162,40 +2702,73 @@
java.io.BufferedReader
java.io.BufferedWriter
java.io.ByteArrayInputStream
+java.io.ByteArrayOutputStream
java.io.Closeable
+java.io.DataInput
java.io.DataInputStream
+java.io.DataOutput
+java.io.DataOutputStream
java.io.EOFException
java.io.Externalizable
java.io.File
java.io.FileDescriptor
+java.io.FileFilter
java.io.FileInputStream
java.io.FileNotFoundException
java.io.FileOutputStream
java.io.FileReader
java.io.FilterInputStream
+java.io.FilterOutputStream
+java.io.FilterReader
+java.io.Flushable
java.io.IOException
java.io.InputStream
java.io.InputStreamReader
java.io.InterruptedIOException
+java.io.InvalidObjectException
+java.io.ObjectInput
java.io.ObjectInputStream
+java.io.ObjectOutput
+java.io.ObjectOutputStream
+java.io.ObjectOutputStream$PutField
java.io.ObjectStreamClass
+java.io.ObjectStreamClass$5
+java.io.ObjectStreamConstants
+java.io.ObjectStreamException
+java.io.ObjectStreamField
java.io.OutputStream
java.io.OutputStreamWriter
+java.io.PrintStream
java.io.PrintWriter
java.io.PushbackInputStream
+java.io.PushbackReader
java.io.RandomAccessFile
java.io.Reader
java.io.Serializable
+java.io.SerializablePermission
+java.io.SerializationHandleMap
java.io.StringReader
java.io.StringWriter
+java.io.UTFDataFormatException
java.io.UnsupportedEncodingException
+java.io.Writer
java.lang.AbstractMethodError
+java.lang.AbstractStringBuilder
+java.lang.Appendable
java.lang.ArrayIndexOutOfBoundsException
+java.lang.AssertionError
+java.lang.AutoCloseable
java.lang.Boolean
+java.lang.BootClassLoader
java.lang.Byte
+java.lang.CaseMapper
+java.lang.CaseMapper$1
java.lang.CharSequence
java.lang.Character
+java.lang.Character$Subset
+java.lang.Character$UnicodeBlock
java.lang.Class
+java.lang.Class$Caches
java.lang.ClassCastException
java.lang.ClassLoader
java.lang.ClassLoader$SystemClassLoader
@@ -2207,23 +2780,32 @@
java.lang.Daemons$Daemon
java.lang.Daemons$FinalizerDaemon
java.lang.Daemons$FinalizerWatchdogDaemon
-java.lang.Daemons$GCDaemon
-java.lang.Daemons$HeapTrimmerDaemon
+java.lang.Daemons$HeapTaskDaemon
java.lang.Daemons$ReferenceQueueDaemon
+java.lang.DexCache
java.lang.Double
java.lang.Enum
+java.lang.Enum$1
java.lang.Error
java.lang.Exception
java.lang.Float
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.IllegalStateException
+java.lang.IllegalThreadStateException
+java.lang.IncompatibleClassChangeError
+java.lang.IndexOutOfBoundsException
java.lang.InstantiationException
java.lang.Integer
+java.lang.IntegralToString
+java.lang.IntegralToString$1
+java.lang.InternalError
java.lang.InterruptedException
java.lang.Iterable
+java.lang.LinkageError
java.lang.Long
java.lang.Math
+java.lang.Math$NoImagePreloadHolder
java.lang.NoClassDefFoundError
java.lang.NoSuchFieldError
java.lang.NoSuchFieldException
@@ -2234,41 +2816,78 @@
java.lang.NumberFormatException
java.lang.Object
java.lang.OutOfMemoryError
+java.lang.Package
+java.lang.Readable
+java.lang.RealToString
+java.lang.RealToString$1
+java.lang.ReflectiveOperationException
java.lang.Runnable
java.lang.Runtime
java.lang.RuntimeException
java.lang.RuntimePermission
java.lang.SecurityException
java.lang.Short
+java.lang.StackOverflowError
+java.lang.StackTraceElement
java.lang.StrictMath
java.lang.String
+java.lang.String$CaseInsensitiveComparator
+java.lang.StringBuffer
java.lang.StringBuilder
+java.lang.StringFactory
+java.lang.StringIndexOutOfBoundsException
+java.lang.StringToReal
java.lang.StringToReal$StringExponentPair
java.lang.System
java.lang.System$PropertiesWithNonOverrideableDefaults
java.lang.Thread
+java.lang.Thread$State
java.lang.Thread$UncaughtExceptionHandler
+java.lang.ThreadDeath
+java.lang.ThreadGroup
java.lang.ThreadLocal
+java.lang.ThreadLocal$Values
java.lang.Throwable
+java.lang.TwoEnumerationsInOne
java.lang.UnsatisfiedLinkError
java.lang.UnsupportedOperationException
+java.lang.VMClassLoader
+java.lang.VirtualMachineError
java.lang.Void
java.lang.annotation.Annotation
java.lang.annotation.Inherited
+java.lang.ref.FinalizerReference
+java.lang.ref.FinalizerReference$Sentinel
+java.lang.ref.PhantomReference
+java.lang.ref.Reference
+java.lang.ref.ReferenceQueue
java.lang.ref.SoftReference
java.lang.ref.WeakReference
+java.lang.reflect.AbstractMethod
+java.lang.reflect.AbstractMethod$GenericInfo
+java.lang.reflect.AccessibleObject
+java.lang.reflect.AnnotatedElement
+java.lang.reflect.Array
+java.lang.reflect.Constructor
java.lang.reflect.Field
+java.lang.reflect.Field$1
java.lang.reflect.GenericArrayType
+java.lang.reflect.GenericDeclaration
+java.lang.reflect.InvocationHandler
java.lang.reflect.InvocationTargetException
+java.lang.reflect.Member
java.lang.reflect.Method
+java.lang.reflect.Method$1
+java.lang.reflect.Modifier
java.lang.reflect.ParameterizedType
+java.lang.reflect.Proxy
+java.lang.reflect.Proxy$1
java.lang.reflect.Type
+java.lang.reflect.TypeVariable
java.lang.reflect.WildcardType
java.math.BigDecimal
java.math.BigInt
java.math.BigInteger
-java.math.Conversion
-java.math.Multiplication
java.math.NativeBN
java.math.RoundingMode
java.net.AddressCache
@@ -2286,18 +2905,24 @@
java.net.JarURLConnection
java.net.MalformedURLException
java.net.PlainSocketImpl
+java.net.ProtocolException
java.net.Proxy
java.net.Proxy$Type
java.net.ProxySelector
java.net.ProxySelectorImpl
java.net.ResponseCache
+java.net.ServerSocket
java.net.Socket
java.net.SocketAddress
java.net.SocketException
java.net.SocketImpl
java.net.SocketOptions
java.net.SocketTimeoutException
+java.net.URI
+java.net.URI$1
+java.net.URI$PartEncoder
java.net.URISyntaxException
+java.net.URL
java.net.URLConnection
java.net.URLConnection$DefaultContentHandler
java.net.URLEncoder
@@ -2305,19 +2930,47 @@
java.net.URLStreamHandler
java.net.URLStreamHandlerFactory
java.net.UnknownHostException
+java.nio.Buffer
+java.nio.BufferOverflowException
+java.nio.BufferUnderflowException
+java.nio.ByteArrayBuffer
+java.nio.ByteBuffer
+java.nio.ByteBufferAsCharBuffer
+java.nio.ByteBufferAsDoubleBuffer
+java.nio.ByteBufferAsFloatBuffer
+java.nio.ByteBufferAsIntBuffer
+java.nio.ByteBufferAsLongBuffer
+java.nio.ByteBufferAsShortBuffer
java.nio.ByteOrder
java.nio.CharArrayBuffer
+java.nio.CharBuffer
java.nio.CharSequenceAdapter
+java.nio.DirectByteBuffer
+java.nio.DoubleBuffer
java.nio.FileChannelImpl
java.nio.FileChannelImpl$1
+java.nio.FileChannelImpl$FileLockImpl
+java.nio.FloatBuffer
+java.nio.IntBuffer
+java.nio.InvalidMarkException
+java.nio.LongBuffer
+java.nio.MappedByteBuffer
+java.nio.MemoryBlock
+java.nio.MemoryBlock$MemoryMappedBlock
+java.nio.MemoryBlock$NonMovableHeapBlock
java.nio.MemoryBlock$UnmanagedBlock
java.nio.NIOAccess
+java.nio.NioUtils
+java.nio.ReadOnlyBufferException
+java.nio.ShortBuffer
java.nio.channels.AsynchronousCloseException
java.nio.channels.ByteChannel
java.nio.channels.Channel
java.nio.channels.ClosedByInterruptException
java.nio.channels.ClosedChannelException
java.nio.channels.FileChannel
+java.nio.channels.FileChannel$MapMode
+java.nio.channels.FileLock
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
java.nio.channels.ReadableByteChannel
@@ -2325,33 +2978,44 @@
java.nio.channels.WritableByteChannel
java.nio.channels.spi.AbstractInterruptibleChannel
java.nio.channels.spi.AbstractInterruptibleChannel$1
+java.nio.charset.CharacterCodingException
java.nio.charset.Charset
java.nio.charset.CharsetDecoder
+java.nio.charset.CharsetDecoderICU
java.nio.charset.CharsetEncoder
java.nio.charset.CharsetEncoderICU
java.nio.charset.CharsetICU
java.nio.charset.CoderResult
+java.nio.charset.CodingErrorAction
+java.nio.charset.IllegalCharsetNameException
java.nio.charset.ModifiedUtf8
java.nio.charset.StandardCharsets
+java.nio.charset.UnsupportedCharsetException
+java.security.AccessControlException
java.security.AccessController
+java.security.BasicPermission
java.security.DigestException
java.security.GeneralSecurityException
+java.security.Guard
java.security.InvalidAlgorithmParameterException
java.security.InvalidKeyException
java.security.Key
java.security.KeyException
java.security.KeyFactorySpi
java.security.KeyManagementException
-java.security.KeyPairGeneratorSpi
java.security.KeyStore
java.security.KeyStoreException
java.security.KeyStoreSpi
java.security.MessageDigest
java.security.MessageDigest$MessageDigestImpl
+java.security.MessageDigestSpi
java.security.NoSuchAlgorithmException
java.security.NoSuchProviderException
+java.security.Permission
java.security.Principal
+java.security.PrivateKey
java.security.PrivilegedAction
+java.security.ProtectionDomain
java.security.Provider
java.security.Provider$Service
java.security.PublicKey
@@ -2359,8 +3023,13 @@
java.security.SecureRandomSpi
java.security.Security
java.security.Security$SecurityDoor
+java.security.Signature
+java.security.Signature$SignatureImpl
+java.security.SignatureException
+java.security.SignatureSpi
java.security.UnrecoverableEntryException
java.security.UnrecoverableKeyException
+java.security.cert.CRL
java.security.cert.CRLException
java.security.cert.CertPath
java.security.cert.CertPathBuilderException
@@ -2390,13 +3059,25 @@
java.security.cert.X509Extension
java.security.interfaces.DSAKey
java.security.interfaces.DSAPublicKey
+java.security.interfaces.ECKey
+java.security.interfaces.ECPrivateKey
+java.security.interfaces.ECPublicKey
java.security.interfaces.RSAKey
+java.security.interfaces.RSAPrivateKey
java.security.interfaces.RSAPublicKey
java.security.spec.AlgorithmParameterSpec
+java.security.spec.ECField
+java.security.spec.ECFieldFp
+java.security.spec.ECParameterSpec
+java.security.spec.ECPoint
+java.security.spec.EllipticCurve
java.security.spec.InvalidKeySpecException
+java.security.spec.InvalidParameterSpecException
+java.security.spec.KeySpec
java.text.AttributedCharacterIterator$Attribute
java.text.Bidi
java.text.Bidi$Run
+java.text.Collator
java.text.DateFormat
java.text.DateFormat$Field
java.text.DateFormatSymbols
@@ -2409,47 +3090,115 @@
java.text.NumberFormat$Field
java.text.ParseException
java.text.ParsePosition
+java.text.RuleBasedCollator
java.text.SimpleDateFormat
java.util.AbstractCollection
+java.util.AbstractList
+java.util.AbstractList$FullListIterator
+java.util.AbstractList$SimpleListIterator
+java.util.AbstractList$SubAbstractList
+java.util.AbstractList$SubAbstractListRandomAccess
java.util.AbstractMap
+java.util.AbstractMap$1
+java.util.AbstractMap$2
+java.util.AbstractMap$2$1
+java.util.AbstractQueue
java.util.AbstractSequentialList
java.util.AbstractSet
java.util.ArrayDeque
java.util.ArrayList
+java.util.ArrayList$ArrayListIterator
java.util.Arrays
java.util.Arrays$ArrayList
java.util.BitSet
java.util.Calendar
java.util.Collection
java.util.Collections
+java.util.Collections$1
+java.util.Collections$2
+java.util.Collections$3
+java.util.Collections$AsLIFOQueue
+java.util.Collections$CheckedCollection
+java.util.Collections$CheckedList
+java.util.Collections$CheckedMap
+java.util.Collections$CheckedRandomAccessList
+java.util.Collections$CheckedSet
+java.util.Collections$CheckedSortedMap
+java.util.Collections$CheckedSortedSet
+java.util.Collections$CopiesList
+java.util.Collections$EmptyList
+java.util.Collections$EmptyMap
+java.util.Collections$EmptySet
+java.util.Collections$ReverseComparator
+java.util.Collections$ReverseComparator2
+java.util.Collections$SetFromMap
+java.util.Collections$SingletonList
+java.util.Collections$SingletonMap
+java.util.Collections$SingletonSet
java.util.Collections$SingletonSet$1
+java.util.Collections$SynchronizedCollection
+java.util.Collections$SynchronizedList
+java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedRandomAccessList
+java.util.Collections$SynchronizedSet
+java.util.Collections$SynchronizedSortedMap
+java.util.Collections$SynchronizedSortedSet
+java.util.Collections$UnmodifiableCollection
java.util.Collections$UnmodifiableCollection$1
+java.util.Collections$UnmodifiableList
+java.util.Collections$UnmodifiableMap
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableMapEntry
+java.util.Collections$UnmodifiableRandomAccessList
+java.util.Collections$UnmodifiableSet
+java.util.Collections$UnmodifiableSortedMap
+java.util.Collections$UnmodifiableSortedSet
java.util.ComparableTimSort
java.util.Comparator
+java.util.ConcurrentModificationException
java.util.Currency
java.util.Date
+java.util.Deque
+java.util.Dictionary
java.util.DualPivotQuicksort
java.util.EnumMap
java.util.EnumSet
+java.util.Enumeration
+java.util.EventListener
java.util.EventObject
java.util.Formattable
+java.util.Formatter
+java.util.Formatter$1
+java.util.Formatter$CachedDecimalFormat
java.util.Formatter$FormatSpecifierParser
java.util.Formatter$FormatToken
java.util.GregorianCalendar
java.util.HashMap
+java.util.HashMap$EntryIterator
+java.util.HashMap$EntrySet
+java.util.HashMap$HashIterator
+java.util.HashMap$HashMapEntry
+java.util.HashMap$KeyIterator
+java.util.HashMap$KeySet
+java.util.HashMap$ValueIterator
+java.util.HashMap$Values
java.util.HashSet
+java.util.Hashtable
java.util.Hashtable$HashIterator
+java.util.Hashtable$HashtableEntry
java.util.Hashtable$KeyEnumeration
java.util.Hashtable$ValueIterator
java.util.Hashtable$Values
java.util.IdentityHashMap
+java.util.IdentityHashMap$IdentityHashMapIterator
+java.util.IllegalFormatException
+java.util.IllformedLocaleException
java.util.Iterator
java.util.LinkedHashMap
java.util.LinkedHashMap$EntryIterator
java.util.LinkedHashMap$KeyIterator
+java.util.LinkedHashMap$LinkedEntry
java.util.LinkedHashMap$LinkedHashIterator
java.util.LinkedHashMap$ValueIterator
java.util.LinkedHashSet
@@ -2460,6 +3209,7 @@
java.util.ListIterator
java.util.Locale
java.util.Locale$Builder
+java.util.Locale$NoImagePreloadHolder
java.util.Map
java.util.Map$Entry
java.util.MapEntry
@@ -2476,7 +3226,8 @@
java.util.Queue
java.util.Random
java.util.RandomAccess
-java.util.Scanner
+java.util.ResourceBundle
+java.util.ResourceBundle$MissingBundle
java.util.Set
java.util.SimpleTimeZone
java.util.SortedMap
@@ -2492,11 +3243,12 @@
java.util.TimerTask
java.util.TreeMap
java.util.TreeMap$1
-java.util.TreeMap$2
java.util.TreeMap$Bound
java.util.TreeMap$Bound$1
java.util.TreeMap$Bound$2
java.util.TreeMap$Bound$3
+java.util.TreeMap$BoundedMap
+java.util.TreeMap$BoundedMap$BoundedIterator
java.util.TreeMap$EntrySet
java.util.TreeMap$EntrySet$1
java.util.TreeMap$KeySet
@@ -2528,31 +3280,41 @@
java.util.concurrent.ConcurrentHashMap$Node
java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.ConcurrentHashMap$Traverser
+java.util.concurrent.ConcurrentHashMap$TreeBin
+java.util.concurrent.ConcurrentHashMap$TreeNode
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentLinkedQueue$Node
java.util.concurrent.ConcurrentMap
-java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArrayList$CowIterator
+java.util.concurrent.CopyOnWriteArraySet
java.util.concurrent.CountDownLatch
java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.Delayed
java.util.concurrent.ExecutionException
java.util.concurrent.Executor
java.util.concurrent.ExecutorService
java.util.concurrent.Executors
java.util.concurrent.Executors$DefaultThreadFactory
java.util.concurrent.Executors$DelegatedExecutorService
+java.util.concurrent.Executors$DelegatedScheduledExecutorService
java.util.concurrent.Executors$FinalizableDelegatedExecutorService
java.util.concurrent.Executors$RunnableAdapter
java.util.concurrent.Future
java.util.concurrent.FutureTask
java.util.concurrent.FutureTask$WaitNode
-java.util.concurrent.LinkedBlockingDeque
java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.PriorityBlockingQueue
+java.util.concurrent.RejectedExecutionException
java.util.concurrent.RejectedExecutionHandler
java.util.concurrent.RunnableFuture
+java.util.concurrent.RunnableScheduledFuture
java.util.concurrent.ScheduledExecutorService
+java.util.concurrent.ScheduledFuture
+java.util.concurrent.ScheduledThreadPoolExecutor
+java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue
+java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
java.util.concurrent.Semaphore
java.util.concurrent.Semaphore$NonfairSync
java.util.concurrent.Semaphore$Sync
@@ -2594,9 +3356,13 @@
java.util.concurrent.locks.ReentrantReadWriteLock$Sync
java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.jar.Attributes
+java.util.jar.Attributes$Name
java.util.jar.JarEntry
java.util.jar.JarFile
java.util.jar.JarFile$JarFileEnumerator
+java.util.jar.Manifest
+java.util.jar.ManifestReader
java.util.jar.StrictJarFile
java.util.logging.ConsoleHandler
java.util.logging.ErrorManager
@@ -2611,21 +3377,39 @@
java.util.logging.LoggingPermission
java.util.logging.SimpleFormatter
java.util.logging.StreamHandler
+java.util.regex.MatchResult
+java.util.regex.Matcher
java.util.regex.Pattern
java.util.regex.PatternSyntaxException
+java.util.regex.Splitter
+java.util.zip.Adler32
java.util.zip.CRC32
+java.util.zip.Checksum
+java.util.zip.DataFormatException
java.util.zip.Deflater
java.util.zip.DeflaterOutputStream
java.util.zip.GZIPInputStream
java.util.zip.GZIPOutputStream
java.util.zip.Inflater
java.util.zip.InflaterInputStream
+java.util.zip.Zip64
+java.util.zip.ZipConstants
+java.util.zip.ZipEntry
+java.util.zip.ZipFile
java.util.zip.ZipFile$1
+java.util.zip.ZipFile$EocdRecord
java.util.zip.ZipFile$RAFStream
+java.util.zip.ZipFile$ZipInflaterInputStream
javax.crypto.BadPaddingException
+javax.crypto.Cipher
+javax.crypto.Cipher$NeedToSet
+javax.crypto.CipherSpi
javax.crypto.IllegalBlockSizeException
javax.crypto.NoSuchPaddingException
-javax.crypto.spec.GCMParameterSpec
+javax.crypto.SecretKey
+javax.crypto.ShortBufferException
+javax.crypto.spec.IvParameterSpec
+javax.crypto.spec.SecretKeySpec
javax.microedition.khronos.egl.EGL
javax.microedition.khronos.egl.EGL10
javax.microedition.khronos.opengles.GL
@@ -2635,17 +3419,22 @@
javax.microedition.khronos.opengles.GL11Ext
javax.microedition.khronos.opengles.GL11ExtensionPack
javax.net.DefaultSocketFactory
+javax.net.ServerSocketFactory
javax.net.SocketFactory
javax.net.ssl.DistinguishedNameParser
+javax.net.ssl.HandshakeCompletedListener
javax.net.ssl.HostnameVerifier
javax.net.ssl.HttpsURLConnection
javax.net.ssl.KeyManager
javax.net.ssl.KeyManagerFactory
javax.net.ssl.KeyManagerFactorySpi
+javax.net.ssl.SSLContext
javax.net.ssl.SSLContextSpi
+javax.net.ssl.SSLEngine
javax.net.ssl.SSLException
javax.net.ssl.SSLPeerUnverifiedException
javax.net.ssl.SSLProtocolException
+javax.net.ssl.SSLServerSocketFactory
javax.net.ssl.SSLSession
javax.net.ssl.SSLSessionContext
javax.net.ssl.SSLSocket
@@ -2657,14 +3446,17 @@
javax.net.ssl.X509KeyManager
javax.net.ssl.X509TrustManager
javax.security.auth.x500.X500Principal
+javax.security.cert.Certificate
javax.security.cert.CertificateException
+javax.security.cert.X509Certificate
javax.xml.parsers.ParserConfigurationException
libcore.icu.AlphabeticIndex
libcore.icu.AlphabeticIndex$ImmutableIndex
libcore.icu.DateIntervalFormat
+libcore.icu.DateIntervalFormat$FormatterCache
+libcore.icu.DateUtilsBridge
libcore.icu.ICU
libcore.icu.LocaleData
-libcore.icu.NativeBreakIterator
libcore.icu.NativeCollation
libcore.icu.NativeConverter
libcore.icu.NativeDecimalFormat
@@ -2672,10 +3464,12 @@
libcore.icu.NativeIDN
libcore.icu.NativeNormalizer
libcore.icu.NativePluralRules
+libcore.icu.RuleBasedCollatorICU
libcore.icu.TimeZoneNames
libcore.icu.Transliterator
libcore.internal.StringPool
libcore.io.AsynchronousCloseMonitor
+libcore.io.BlockGuardOs
libcore.io.BufferIterator
libcore.io.DropBox
libcore.io.DropBox$DefaultReporter
@@ -2683,14 +3477,21 @@
libcore.io.EventLogger
libcore.io.EventLogger$DefaultReporter
libcore.io.EventLogger$Reporter
+libcore.io.ForwardingOs
libcore.io.HeapBufferIterator
libcore.io.IoBridge
+libcore.io.IoUtils
libcore.io.IoUtils$FileReader
+libcore.io.Libcore
+libcore.io.Memory
libcore.io.MemoryMappedFile
libcore.io.NioBufferIterator
+libcore.io.Os
+libcore.io.Posix
libcore.io.Streams
libcore.math.MathUtils
-libcore.net.MimeUtils
+libcore.net.NetworkSecurityPolicy
+libcore.net.UriCodec
libcore.net.event.NetworkEventDispatcher
libcore.net.event.NetworkEventListener
libcore.net.url.FileHandler
@@ -2700,11 +3501,23 @@
libcore.net.url.JarURLConnectionImpl
libcore.net.url.JarURLConnectionImpl$JarURLConnectionInputStream
libcore.net.url.UrlUtils
+libcore.reflect.AnnotationAccess
libcore.reflect.AnnotationFactory
libcore.reflect.AnnotationMember
libcore.reflect.AnnotationMember$DefaultValues
+libcore.reflect.GenericSignatureParser
+libcore.reflect.InternalNames
+libcore.reflect.ListOfTypes
libcore.reflect.ListOfVariables
libcore.reflect.ParameterizedTypeImpl
+libcore.reflect.Types
+libcore.util.BasicLruCache
+libcore.util.CharsetUtils
+libcore.util.CollectionUtils
+libcore.util.CollectionUtils$1
+libcore.util.CollectionUtils$1$1
+libcore.util.EmptyArray
+libcore.util.Objects
libcore.util.ZoneInfo
libcore.util.ZoneInfo$CheckedArithmeticException
libcore.util.ZoneInfo$WallTime
@@ -2716,6 +3529,9 @@
org.apache.commons.logging.impl.Jdk14Logger
org.apache.commons.logging.impl.WeakHashtable
org.apache.harmony.dalvik.NativeTestTarget
+org.apache.harmony.dalvik.ddmc.Chunk
+org.apache.harmony.dalvik.ddmc.ChunkHandler
+org.apache.harmony.dalvik.ddmc.DdmServer
org.apache.harmony.dalvik.ddmc.DdmVmInternal
org.apache.harmony.luni.internal.util.TimezoneGetter
org.apache.harmony.security.asn1.ASN1Any
@@ -2744,12 +3560,11 @@
org.apache.harmony.security.asn1.BerOutputStream
org.apache.harmony.security.asn1.DerInputStream
org.apache.harmony.security.asn1.DerOutputStream
+org.apache.harmony.security.fortress.Engine
org.apache.harmony.security.fortress.Engine$ServiceCacheEntry
org.apache.harmony.security.fortress.Engine$SpiAndProvider
org.apache.harmony.security.fortress.SecurityAccess
org.apache.harmony.security.fortress.Services
-org.apache.harmony.security.pkcs7.ContentInfo$1
-org.apache.harmony.security.pkcs7.SignedData
org.apache.harmony.security.provider.crypto.CryptoProvider
org.apache.harmony.security.utils.AlgNameMapper
org.apache.harmony.security.utils.AlgNameMapperSource
@@ -2763,11 +3578,8 @@
org.apache.harmony.security.x501.DirectoryString$1
org.apache.harmony.security.x501.Name
org.apache.harmony.security.x501.Name$1
-org.apache.harmony.security.x509.TBSCertificate
org.apache.harmony.xml.ExpatAttributes
org.apache.harmony.xml.ExpatParser
-org.apache.harmony.xml.dom.DocumentImpl
-org.apache.harmony.xml.dom.InnerNodeImpl
org.apache.http.ConnectionReuseStrategy
org.apache.http.FormattedHeader
org.apache.http.Header
@@ -2859,7 +3671,6 @@
org.apache.http.conn.ssl.SSLSocketFactory
org.apache.http.conn.ssl.StrictHostnameVerifier
org.apache.http.conn.ssl.X509HostnameVerifier
-org.apache.http.conn.util.InetAddressUtils
org.apache.http.cookie.CookieSpecFactory
org.apache.http.cookie.CookieSpecRegistry
org.apache.http.cookie.MalformedCookieException
@@ -2870,9 +3681,7 @@
org.apache.http.entity.HttpEntityWrapper
org.apache.http.impl.AbstractHttpClientConnection
org.apache.http.impl.DefaultConnectionReuseStrategy
-org.apache.http.impl.DefaultHttpClientConnection
org.apache.http.impl.DefaultHttpResponseFactory
-org.apache.http.impl.DefaultHttpServerConnection
org.apache.http.impl.EnglishReasonPhraseCatalog
org.apache.http.impl.HttpConnectionMetricsImpl
org.apache.http.impl.SocketHttpClientConnection
@@ -2903,7 +3712,6 @@
org.apache.http.impl.conn.IdleConnectionHandler
org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
org.apache.http.impl.conn.ProxySelectorRoutePlanner
-org.apache.http.impl.conn.ProxySelectorRoutePlanner$1
org.apache.http.impl.conn.tsccm.AbstractConnPool
org.apache.http.impl.conn.tsccm.BasicPoolEntry
org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
@@ -2932,7 +3740,6 @@
org.apache.http.impl.io.AbstractSessionInputBuffer
org.apache.http.impl.io.AbstractSessionOutputBuffer
org.apache.http.impl.io.ChunkedInputStream
-org.apache.http.impl.io.ContentLengthInputStream
org.apache.http.impl.io.ContentLengthOutputStream
org.apache.http.impl.io.HttpRequestWriter
org.apache.http.impl.io.HttpTransportMetricsImpl
@@ -2984,8 +3791,18 @@
org.apache.http.util.ByteArrayBuffer
org.apache.http.util.CharArrayBuffer
org.apache.http.util.LangUtils
+org.ccil.cowan.tagsoup.AttributesImpl
+org.ccil.cowan.tagsoup.AutoDetector
+org.ccil.cowan.tagsoup.Element
+org.ccil.cowan.tagsoup.ElementType
+org.ccil.cowan.tagsoup.HTMLModels
org.ccil.cowan.tagsoup.HTMLScanner
+org.ccil.cowan.tagsoup.HTMLSchema
org.ccil.cowan.tagsoup.Parser
+org.ccil.cowan.tagsoup.Parser$1
+org.ccil.cowan.tagsoup.ScanHandler
+org.ccil.cowan.tagsoup.Scanner
+org.ccil.cowan.tagsoup.Schema
org.json.JSON
org.json.JSONArray
org.json.JSONException
@@ -3007,7 +3824,9 @@
org.xml.sax.SAXNotRecognizedException
org.xml.sax.SAXNotSupportedException
org.xml.sax.XMLReader
+org.xml.sax.ext.LexicalHandler
org.xml.sax.helpers.DefaultHandler
org.xmlpull.v1.XmlPullParser
org.xmlpull.v1.XmlPullParserException
org.xmlpull.v1.XmlSerializer
+sun.misc.Unsafe
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 82d9a2f..54180f4 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -851,13 +851,13 @@
* Returns the field ID
*/
- public Script.FieldID getField() { return mField; }
+ Script.FieldID getField() { return mField; }
/**
* Returns the value
*/
- public Object getValue() { return mValue; }
+ Object getValue() { return mValue; }
}
/**
@@ -995,6 +995,8 @@
*
* @param name name for the script group. Legal names can only contain letters, digits,
* '-', or '_'. The name can be no longer than 100 characters.
+ * Try to use unique names, to avoid name conflicts and reduce
+ * the cost of group creation.
* @param outputs futures intended as outputs of the script group
* @return a script group
*/
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index f7e81b0..aa72fba 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -22,7 +22,12 @@
/**
*
- * BLAS
+ * ScriptIntrinsicBLAS class provides high performance RenderScript APIs to BLAS.
+ *
+ * The BLAS (Basic Linear Algebra Subprograms) are routines that provide standard
+ * building blocks for performing basic vector and matrix operations.
+ *
+ * For detailed description of BLAS, please refer to http://www.netlib.org/blas/
*
**/
public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
@@ -179,24 +184,40 @@
private static final int RsBlas_bnnm = 1000;
/**
+ * Create an intrinsic to access BLAS subroutines.
+ *
+ * @param rs The RenderScript context
+ * @return ScriptIntrinsicBLAS
*/
public static ScriptIntrinsicBLAS create(RenderScript rs) {
long id = rs.nScriptIntrinsicCreate(13, Element.U32(rs).getID(rs));
return new ScriptIntrinsicBLAS(id, rs);
}
+ /**
+ * @hide
+ */
@IntDef({NO_TRANSPOSE, TRANSPOSE, CONJ_TRANSPOSE})
@Retention(RetentionPolicy.SOURCE)
public @interface Transpose {}
+ /**
+ * @hide
+ */
@IntDef({UPPER, LOWER})
@Retention(RetentionPolicy.SOURCE)
public @interface Uplo {}
+ /**
+ * @hide
+ */
@IntDef({NON_UNIT, UNIT})
@Retention(RetentionPolicy.SOURCE)
public @interface Diag {}
+ /**
+ * @hide
+ */
@IntDef({LEFT, RIGHT})
@Retention(RetentionPolicy.SOURCE)
public @interface Side {}
@@ -280,24 +301,88 @@
throw new RSRuntimeException("Incorrect vector dimensions for GEMV");
}
}
+
+ /**
+ * SGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d58/sgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
int M = A.getType().getY();
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
int M = A.getType().getY();
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d8a/cgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
int M = A.getType().getY();
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d40/zgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
int M = A.getType().getY();
@@ -305,6 +390,30 @@
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+ /**
+ * SGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d46/sgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
// GBMV has the same validation requirements as GEMV + KL and KU >= 0
validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
@@ -315,6 +424,31 @@
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU);
}
+
+ /**
+ * DGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d3f/dgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
// GBMV has the same validation requirements as GEMV + KL and KU >= 0
validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
@@ -325,6 +459,31 @@
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU);
}
+
+ /**
+ * CGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d75/cgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
// GBMV has the same validation requirements as GEMV + KL and KU >= 0
validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
@@ -335,6 +494,31 @@
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, KL, KU);
}
+
+ /**
+ * ZGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d46/zgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
// GBMV has the same validation requirements as GEMV + KL and KU >= 0
validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
@@ -403,27 +587,103 @@
return N;
}
+ /**
+ * STRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d45/strmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/d7e/dtrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d78/ctrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/dd1/ztrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+ /**
+ * STBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d7d/stbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBMV has the same requirements as TRMV + K >= 0
if (K < 0) {
@@ -433,6 +693,28 @@
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d29/dtbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBMV has the same requirements as TRMV + K >= 0
if (K < 0) {
@@ -442,6 +724,28 @@
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/dcd/ctbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBMV has the same requirements as TRMV + K >= 0
if (K < 0) {
@@ -451,6 +755,28 @@
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d39/ztbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBMV has the same requirements as TRMV + K >= 0
if (K < 0) {
@@ -460,22 +786,124 @@
int N = A.getType().getY();
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * STPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/db1/stpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/dcd/dtpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dbb/ctpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d9e/ztpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * STRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d2a/strsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
// TRSV is the same as TRMV
validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -483,6 +911,20 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d96/dtrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
// TRSV is the same as TRMV
validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -490,6 +932,20 @@
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dc8/ctrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
// TRSV is the same as TRMV
validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -497,6 +953,20 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d2f/ztrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
// TRSV is the same as TRMV
validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -504,6 +974,28 @@
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * STBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d1f/stbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBSV is the same as TRMV + K >= 0
validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -513,6 +1005,28 @@
}
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dcf/dtbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBSV is the same as TRMV + K >= 0
validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -522,6 +1036,28 @@
}
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d5f/ctbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBSV is the same as TRMV + K >= 0
validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -531,6 +1067,28 @@
}
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d5a/ztbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
// TBSV is the same as TRMV + K >= 0
validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
@@ -540,21 +1098,109 @@
}
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * STPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d7c/stpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
// TPSV is same as TPMV
int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d84/dtpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
// TPSV is same as TPMV
int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * CTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d56/ctpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
// TPSV is same as TPMV
int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
}
+
+ /**
+ * ZTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/da/d57/ztpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
public void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
// TPSV is same as TPMV
int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
@@ -768,10 +1414,49 @@
return N;
}
+ /**
+ * SSYMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d94/ssymv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * SSBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/da1/ssbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
// SBMV is the same as SYMV + K >= 0
if (K < 0) {
@@ -780,36 +1465,186 @@
int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * SSPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d68/sspmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
int N = validateSPMV(Element.F32(mRS), Uplo, Ap, X, incX, Y, incY);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * SGER performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d5c/sger_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
public void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
int M = A.getType().getY();
int N = A.getType().getX();
validateGER(Element.F32(mRS), X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * SSYR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/dac/ssyr_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
public void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0);
}
+
+ /**
+ * SSPR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d9b/sspr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
public void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0);
}
+
+ /**
+ * SSYR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d99/ssyr2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
public void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
int N = validateSYR2(Element.F32(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * SSPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d3e/sspr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
public void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
int N = validateSPR2(Element.F32(mRS), Uplo, X, incX, Y, incY, Ap);
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DSYMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/dbe/dsymv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DSBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d1e/dsbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
// SBMV is the same as SYMV + K >= 0
if (K < 0) {
@@ -818,28 +1653,138 @@
int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DSPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d85/dspmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
int N = validateSPMV(Element.F64(mRS), Uplo, Ap, X, incX, Y, incY);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DGER performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
public void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
int M = A.getType().getY();
int N = A.getType().getX();
validateGER(Element.F64(mRS), X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DSYR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d60/dsyr_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
public void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DSPR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/dba/dspr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
public void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0);
}
+
+ /**
+ * DSYR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d41/dsyr2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
public void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
int N = validateSYR2(Element.F64(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * DSPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d9e/dspr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
public void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
int N = validateSPR2(Element.F64(mRS), Uplo, X, incX, Y, incY, Ap);
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0);
@@ -876,11 +1821,50 @@
}
+ /**
+ * CHEMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d51/chemv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
// HEMV is the same as SYR2 validation-wise
int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CHBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/dc2/chbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
// HBMV is the same as SYR2 validation-wise
int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
@@ -889,17 +1873,69 @@
}
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CHPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d06/chpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
// HPMV is the same as SPR2
int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CGERU performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d5f/cgeru_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
int M = A.getType().getY();
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CGERC performs the rank 1 operation
+ * A := alpha*x*y**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d84/cgerc_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
// same as GERU
validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
@@ -907,31 +1943,143 @@
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CHER performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d6d/cher_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
// same as SYR
int N = validateSYR(Element.F32_2(mRS), Uplo, X, incX, A);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0);
}
+
+ /**
+ * CHPR performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/dcd/chpr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
// equivalent to SPR for validation
int N = validateSPR(Element.F32_2(mRS), Uplo, X, incX, Ap);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0);
}
+
+ /**
+ * CHER2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d87/cher2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
// same as SYR2
int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * CHPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d44/chpr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
public void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
// same as SPR2
int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, Ap.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZHEMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/ddd/zhemv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
// HEMV is the same as SYR2 validation-wise
int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZHBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d1a/zhbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
// HBMV is the same as SYR2 validation-wise
int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
@@ -940,17 +2088,69 @@
}
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZHPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d60/zhpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
public void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
// HPMV is the same as SPR2
int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZGERU performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d12/zgeru_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
int M = A.getType().getY();
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZGERC performs the rank 1 operation
+ * A := alpha*x*y**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/dad/zgerc_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
// same as GERU
validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
@@ -958,21 +2158,93 @@
int N = A.getType().getX();
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZHER performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d0e/zher_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
// same as SYR
int N = validateSYR(Element.F64_2(mRS), Uplo, X, incX, A);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0);
}
+
+ /**
+ * ZHPR performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/de1/zhpr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
// equivalent to SPR for validation
int N = validateSPR(Element.F64_2(mRS), Uplo, X, incX, Ap);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0);
}
+
+ /**
+ * ZHER2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/da/d8a/zher2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
// same as SYR2
int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
}
+
+ /**
+ * ZHPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d5/d52/zhpr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
public void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
// same as SPR2
int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
@@ -1051,6 +2323,20 @@
}
+ /**
+ * SGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/de2/sgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
public void SGEMM(@Transpose int TransA, @Transpose int TransB, float alpha, Allocation A,
Allocation B, float beta, Allocation C) {
validateTranspose(TransA);
@@ -1073,6 +2359,21 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, A.getID(mRS), B.getID(mRS),
beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * DGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
public void DGEMM(@Transpose int TransA, @Transpose int TransB, double alpha, Allocation A,
Allocation B, double beta, Allocation C) {
validateTranspose(TransA);
@@ -1094,6 +2395,21 @@
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, A.getID(mRS), B.getID(mRS),
beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * CGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T or op(X) = X**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d5b/cgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CGEMM(@Transpose int TransA, @Transpose int TransB, Float2 alpha, Allocation A,
Allocation B, Float2 beta, Allocation C) {
validateTranspose(TransA);
@@ -1116,6 +2432,20 @@
beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+ /**
+ * ZGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T or op(X) = X**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d76/zgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2
+ */
public void ZGEMM(@Transpose int TransA, @Transpose int TransB, Double2 alpha, Allocation A,
Allocation B, Double2 beta, Allocation C) {
validateTranspose(TransA);
@@ -1138,6 +2468,20 @@
beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+ /**
+ * SSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d42/ssymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
public void SSYMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A,
Allocation B, float beta, Allocation C) {
validateSide(Side);
@@ -1150,6 +2494,21 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS),
beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * DSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/db0/dsymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
public void DSYMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A,
Allocation B, double beta, Allocation C) {
validateSide(Side);
@@ -1161,6 +2520,21 @@
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS),
beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * CSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d59/csymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CSYMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A,
Allocation B, Float2 beta, Allocation C) {
validateSide(Side);
@@ -1172,6 +2546,21 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS),
beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d51/zsymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZSYMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A,
Allocation B, Double2 beta, Allocation C) {
validateSide(Side);
@@ -1184,6 +2573,19 @@
beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+ /**
+ * SSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d40/ssyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
public void SSYRK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
validateTranspose(Trans);
validateUplo(Uplo);
@@ -1198,6 +2600,19 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), 0, beta, C.getID(mRS), 0, 0, 0, 0);
}
+ /**
+ * DSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/d05/dsyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
public void DSYRK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
validateTranspose(Trans);
validateUplo(Uplo);
@@ -1210,6 +2625,20 @@
}
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), 0, beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * CSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d6a/csyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CSYRK(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Float2 beta, Allocation C) {
validateTranspose(Trans);
validateUplo(Uplo);
@@ -1223,6 +2652,20 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), 0, beta.x, beta.y,
C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d54/zsyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Double2 beta, Allocation C) {
validateTranspose(Trans);
validateUplo(Uplo);
@@ -1262,6 +2705,21 @@
throw new RSRuntimeException("Invalid A and B in SYR2K");
}
}
+
+ /**
+ * SSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d3d/ssyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
public void SSYR2K(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, Allocation B, float beta, Allocation C) {
validateUplo(Uplo);
validateSYR2K(Element.F32(mRS), Trans, A, B, C);
@@ -1273,6 +2731,21 @@
}
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), B.getID(mRS), beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * DSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/dec/dsyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
public void DSYR2K(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, Allocation B, double beta, Allocation C) {
validateUplo(Uplo);
validateSYR2K(Element.F64(mRS), Trans, A, B, C);
@@ -1284,6 +2757,21 @@
}
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), B.getID(mRS), beta, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * CSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d7e/csyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CSYR2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
validateUplo(Uplo);
validateSYR2K(Element.F32_2(mRS), Trans, A, B, C);
@@ -1295,6 +2783,21 @@
}
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d20/zsyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZSYR2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
validateUplo(Uplo);
validateSYR2K(Element.F64_2(mRS), Trans, A, B, C);
@@ -1334,6 +2837,22 @@
}
}
}
+
+ /**
+ * STRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d01/strmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ */
public void STRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1341,6 +2860,22 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha, A.getID(mRS), B.getID(mRS), 0.f, 0, 0, 0, 0, 0);
}
+
+ /**
+ * DTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d19/dtrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ */
public void DTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1348,6 +2883,22 @@
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0);
}
+
+ /**
+ * CTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d9b/ctrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ */
public void CTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1355,6 +2906,22 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0);
}
+
+ /**
+ * ZTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/de1/ztrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ */
public void ZTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1392,6 +2959,22 @@
}
}
}
+
+ /**
+ * STRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d8b/strsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ */
public void STRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1399,6 +2982,22 @@
mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0);
}
+
+ /**
+ * DTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/da7/dtrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ */
public void DTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1406,6 +3005,22 @@
mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0);
}
+
+ /**
+ * CTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d30/ctrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ */
public void CTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1413,6 +3028,22 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0);
}
+
+ /**
+ * ZTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d39/ztrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ */
public void ZTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
validateUplo(Uplo);
validateDiag(Diag);
@@ -1444,12 +3075,42 @@
throw new RSRuntimeException("Called HEMM with mismatched B and C");
}
}
+
+ /**
+ * CHEMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d66/chemm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CHEMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
validateUplo(Uplo);
validateHEMM(Element.F32_2(mRS), Side, A, B, C);
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZHEMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d3e/zhemm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZHEMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
validateUplo(Uplo);
validateHEMM(Element.F64_2(mRS), Side, A, B, C);
@@ -1477,6 +3138,20 @@
}
}
}
+
+ /**
+ * CHERK performs one of the hermitian rank k operations
+ * C := alpha*A*A**H + beta*C or C := alpha*A**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d52/cherk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CHERK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
validateUplo(Uplo);
validateHERK(Element.F32_2(mRS), Trans, A, C);
@@ -1489,6 +3164,20 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
alpha, 0, A.getID(mRS), 0, beta, 0, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZHERK performs one of the hermitian rank k operations
+ * C := alpha*A*A**H + beta*C or C := alpha*A**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/db1/zherk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZHERK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
validateUplo(Uplo);
validateHERK(Element.F64_2(mRS), Trans, A, C);
@@ -1526,6 +3215,21 @@
throw new RSRuntimeException("Called HER2K with invalid A and B matrices");
}
}
+
+ /**
+ * CHER2K performs one of the hermitian rank 2k operations
+ * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C or C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d82/cher2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
public void CHER2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, float beta, Allocation C) {
validateUplo(Uplo);
validateHER2K(Element.F32_2(mRS), Trans, A, B, C);
@@ -1538,6 +3242,21 @@
mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0);
}
+
+ /**
+ * ZHER2K performs one of the hermitian rank 2k operations
+ * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C or C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/dfa/zher2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
public void ZHER2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, double beta, Allocation C) {
validateUplo(Uplo);
validateHER2K(Element.F64_2(mRS), Trans, A, B, C);
@@ -1553,9 +3272,19 @@
/**
- *
- * 8-bit GEMM-like operation for neural networks
- *
+ * 8-bit GEMM-like operation for neural networks: C = B.transposed() * A
+ * Calculations are done in 1.10.21 fixed-point format for the final output,
+ * just before there's a shift down to drop the fractional parts. The output
+ * values are gated to 0 to 255 to fit in a byte, but the 10-bit format
+ * gives some headroom to avoid wrapping around on small overflows.
+ *
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#U8}.
+ * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#U8}.
+ * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#U8}.
+ * @param c_offset The offset for all values in matrix C.
+ * @param c_mult The multiplier for all values in matrix C, e.g C[i,j] = (C[i,j] + c_offset) * c_mult.
**/
public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7bcbcfb..57769e7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3351,6 +3351,8 @@
case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
+ // Also always dispatch the event that assist is reading context.
+ case AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT:
// Also windows changing should always be anounced.
case AccessibilityEvent.TYPE_WINDOWS_CHANGED: {
return true;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 839b87a..d58d3721 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1611,8 +1611,7 @@
if (mAlarmBatches.size() > 0) {
final Batch firstWakeup = findFirstWakeupBatchLocked();
final Batch firstBatch = mAlarmBatches.get(0);
- // always update the kernel alarms, as a backstop against missed wakeups
- if (firstWakeup != null) {
+ if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
mNextWakeup = firstWakeup.start;
setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
}
@@ -1625,8 +1624,7 @@
nextNonWakeup = mNextNonWakeupDeliveryTime;
}
}
- // always update the kernel alarm, as a backstop against missed wakeups
- if (nextNonWakeup != 0) {
+ if (nextNonWakeup != 0 && mNextNonWakeup != nextNonWakeup) {
mNextNonWakeup = nextNonWakeup;
setLocked(ELAPSED_REALTIME, nextNonWakeup);
}
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 98f0b45..7f124dc 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;
@@ -92,6 +93,9 @@
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -136,13 +140,12 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet4Address;
-import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -326,7 +329,7 @@
/**
* used to add a network request with a pending intent
- * includes a NetworkRequestInfo
+ * obj = NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
@@ -356,6 +359,12 @@
*/
private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30;
+ /**
+ * used to add a network listener with a pending intent
+ * obj = NetworkRequestInfo
+ */
+ private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
+
/** Handler used for internal events. */
final private InternalHandler mHandler;
/** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -408,6 +417,20 @@
// sequence number of NetworkRequests
private int mNextNetworkRequestId = 1;
+ // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results
+ private static final int MAX_VALIDATION_LOGS = 10;
+ private final ArrayDeque<Pair<Network,ReadOnlyLocalLog>> mValidationLogs =
+ new ArrayDeque<Pair<Network,ReadOnlyLocalLog>>(MAX_VALIDATION_LOGS);
+
+ private void addValidationLogs(ReadOnlyLocalLog log, Network network) {
+ synchronized(mValidationLogs) {
+ while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
+ mValidationLogs.removeLast();
+ }
+ mValidationLogs.addFirst(new Pair(network, log));
+ }
+ }
+
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -1553,7 +1576,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
@@ -1709,11 +1732,9 @@
return ret;
}
- private boolean shouldPerformDiagnostics(String[] args) {
+ private boolean argsContain(String[] args, String target) {
for (String arg : args) {
- if (arg.equals("--diag")) {
- return true;
- }
+ if (arg.equals(target)) return true;
}
return false;
}
@@ -1731,7 +1752,7 @@
}
final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
- if (shouldPerformDiagnostics(args)) {
+ if (argsContain(args, "--diag")) {
final long DIAG_TIME_MS = 5000;
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
// Start gathering diagnostic information.
@@ -1818,6 +1839,19 @@
}
pw.decreaseIndent();
}
+
+ if (argsContain(args, "--short") == false) {
+ pw.println();
+ synchronized (mValidationLogs) {
+ pw.println("mValidationLogs (most recent first):");
+ for (Pair<Network,ReadOnlyLocalLog> p : mValidationLogs) {
+ pw.println(p.first);
+ pw.increaseIndent();
+ p.second.dump(fd, pw, args);
+ pw.decreaseIndent();
+ }
+ }
+ }
}
private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
@@ -1863,7 +1897,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;
}
@@ -1950,20 +1991,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
@@ -1971,10 +2008,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;
}
@@ -1987,21 +2020,28 @@
}
case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
final int netId = msg.arg2;
- if (msg.arg1 == 0) {
- setProvNotificationVisibleIntent(false, netId, null, 0, null, null);
+ 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, false);
} 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);
+ nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(),
+ (PendingIntent)msg.obj, nai.networkMisc.explicitlySelected);
}
break;
}
@@ -2068,15 +2108,6 @@
log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
}
// A network agent has disconnected.
- if (nai.created) {
- // Tell netd to clean up the configuration for this network
- // (routing rules, DNS, etc).
- try {
- mNetd.removeNetwork(nai.network.netId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
- }
- }
// TODO - if we move the logic to the network agent (have them disconnect
// because they lost all their requests or because their score isn't good)
// then they would disconnect organically, report their new state and then
@@ -2095,8 +2126,9 @@
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
synchronized (mNetworkForNetId) {
+ // Remove the NetworkAgent, but don't mark the netId as
+ // available until we've told netd to delete it below.
mNetworkForNetId.remove(nai.network.netId);
- mNetIdInUse.delete(nai.network.netId);
}
// Since we've lost the network, go through all the requests that
// it was satisfying and see if any other factory can satisfy them.
@@ -2138,9 +2170,28 @@
rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED,
ReapUnvalidatedNetworks.DONT_REAP);
}
+ if (nai.created) {
+ // Tell netd to clean up the configuration for this network
+ // (routing rules, DNS, etc).
+ // This may be slow as it requires a lot of netd shelling out to ip and
+ // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
+ // after we've rematched networks with requests which should make a potential
+ // fallback network the default or requested a new network from the
+ // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
+ // long time.
+ try {
+ mNetd.removeNetwork(nai.network.netId);
+ } catch (Exception e) {
+ loge("Exception removing network: " + e);
+ }
+ }
+ synchronized (mNetworkForNetId) {
+ mNetIdInUse.delete(nai.network.netId);
+ }
+ } else {
+ NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
+ if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
}
- NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
- if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
}
// If this method proves to be too slow then we can maintain a separate
@@ -2185,7 +2236,9 @@
// Not setting bestNetwork here as a listening NetworkRequest may be
// satisfied by multiple Networks. Instead the request is added to
// each satisfying Network and notified about each.
- network.addRequest(nri.request);
+ if (!network.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + network.name() + " already has " + nri.request);
+ }
notifyNetworkCallback(network, nri);
} else if (bestNetwork == null ||
bestNetwork.getCurrentScore() < network.getCurrentScore()) {
@@ -2196,7 +2249,9 @@
if (bestNetwork != null) {
if (DBG) log("using " + bestNetwork.name());
unlinger(bestNetwork);
- bestNetwork.addRequest(nri.request);
+ if (!bestNetwork.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + bestNetwork.name() + " already has " + nri.request);
+ }
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
notifyNetworkCallback(bestNetwork, nri);
if (nri.request.legacyType != TYPE_NONE) {
@@ -2369,7 +2424,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);
}
@@ -2405,7 +2460,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;
}
@@ -2419,7 +2474,7 @@
PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
setProvNotificationVisibleIntent(true, nai.network.netId, NotificationType.NO_INTERNET,
- nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), pendingIntent);
+ nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), pendingIntent, true);
}
private class InternalHandler extends Handler {
@@ -2480,7 +2535,8 @@
handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
break;
}
- case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: {
+ case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
+ case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
handleRegisterNetworkRequestWithIntent(msg);
break;
}
@@ -2655,7 +2711,10 @@
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
- if (nai == null) return;
+ if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
+ nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
+ return;
+ }
// Revalidate if the app report does not match our current validated state.
if (hasConnectivity == nai.lastValidated) return;
final int uid = Binder.getCallingUid();
@@ -3211,7 +3270,7 @@
// Concatenate the range of types onto the range of NetIDs.
int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
setProvNotificationVisibleIntent(visible, id, NotificationType.SIGN_IN,
- networkType, null, pendingIntent);
+ networkType, null, pendingIntent, false);
}
/**
@@ -3230,11 +3289,12 @@
* we concatenate the range of types with the range of NetIDs.
*/
private void setProvNotificationVisibleIntent(boolean visible, int id,
- NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent) {
+ NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent,
+ boolean highPriority) {
if (DBG) {
log("setProvNotificationVisibleIntent " + notifyType + " visible=" + visible
+ " networkType=" + getNetworkTypeName(networkType)
- + " extraInfo=" + extraInfo);
+ + " extraInfo=" + extraInfo + " highPriority=" + highPriority);
}
Resources r = Resources.getSystem();
@@ -3289,6 +3349,12 @@
.setContentTitle(title)
.setContentText(details)
.setContentIntent(intent)
+ .setLocalOnly(true)
+ .setPriority(highPriority ?
+ Notification.PRIORITY_HIGH :
+ Notification.PRIORITY_DEFAULT)
+ .setDefaults(Notification.DEFAULT_ALL)
+ .setOnlyAlertOnce(true)
.build();
try {
@@ -3549,12 +3615,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");
@@ -3623,6 +3701,7 @@
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
+ ensureImmutableCapabilities(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId());
@@ -3689,6 +3768,18 @@
@Override
public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation) {
+ checkNotNull(operation, "PendingIntent cannot be null.");
+ if (!hasWifiNetworkListenPermission(networkCapabilities)) {
+ enforceAccessPermission();
+ }
+
+ NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
+ networkCapabilities), TYPE_NONE, nextNetworkRequestId());
+ if (DBG) log("pendingListenForNetwork for " + networkRequest + " to trigger " + operation);
+ NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
+ NetworkRequestInfo.LISTEN);
+
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
}
@Override
@@ -3780,6 +3871,7 @@
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
+ addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network);
if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
return nai.network.netId;
@@ -3923,51 +4015,10 @@
return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
}
- // TODO: investigate moving this into LinkProperties, if only to make more accurate
- // the isProvisioned() checks.
- private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) {
- final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>();
- final List<RouteInfo> allRoutes = lp.getAllRoutes();
- for (InetAddress nameserver : lp.getDnsServers()) {
- // If the LinkProperties doesn't include a route to the nameserver, ignore it.
- final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver);
- if (bestRoute == null) {
- continue;
- }
-
- // TODO: better source address evaluation for destination addresses.
- if (nameserver instanceof Inet4Address) {
- if (!lp.hasIPv4Address()) {
- continue;
- }
- } else if (nameserver instanceof Inet6Address) {
- if (nameserver.isLinkLocalAddress()) {
- if (((Inet6Address)nameserver).getScopeId() == 0) {
- // For now, just make sure link-local DNS servers have
- // scopedIds set, since DNS lookups will fail otherwise.
- // TODO: verify the scopeId matches that of lp's interface.
- continue;
- }
- } else {
- if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) {
- // TODO: reconsider all corner cases (disconnected ULA networks, ...).
- continue;
- }
- }
- }
-
- dnsServers.add(nameserver);
- }
- return Collections.unmodifiableList(dnsServers);
- }
-
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
boolean flush, boolean useDefaultDns) {
- // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the
- // route to a DNS server has been removed (only really applicable in special cases
- // where there is no default route).
if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp);
+ Collection<InetAddress> dnses = newLp.getDnsServers();
if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
dnses = new ArrayList();
dnses.add(mDefaultDns);
@@ -4012,18 +4063,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);
}
}
@@ -4197,6 +4265,7 @@
// Find and migrate to this Network any NetworkRequests for
// which this network is now the best.
ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
+ ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>();
if (VDBG) log(" network has: " + newNetwork.networkCapabilities);
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
@@ -4215,7 +4284,7 @@
if (!nri.isRequest) {
// This is not a request, it's a callback listener.
// Add it to newNetwork regardless of score.
- newNetwork.addRequest(nri.request);
+ if (newNetwork.addRequest(nri.request)) addedRequests.add(nri);
continue;
}
@@ -4238,7 +4307,10 @@
}
unlinger(newNetwork);
mNetworkForRequestId.put(nri.request.requestId, newNetwork);
- newNetwork.addRequest(nri.request);
+ if (!newNetwork.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
+ }
+ addedRequests.add(nri);
keep = true;
// Tell NetworkFactories about the new score, so they can stop
// trying to connect if they know they cannot match it.
@@ -4281,7 +4353,7 @@
// do this after the default net is switched, but
// before LegacyTypeTracker sends legacy broadcasts
- notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
+ for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri);
if (isNewDefault) {
// Maintain the illusion: since the legacy API only
@@ -4363,15 +4435,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
@@ -4380,9 +4458,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(),
@@ -4509,7 +4587,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 8dd087a..dc203ff 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -45,6 +45,7 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -96,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;
@@ -111,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;
@@ -190,10 +188,6 @@
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
}
- } else if (ACTION_ENTER_INACTIVE_STATE.equals(intent.getAction())) {
- synchronized (DeviceIdleController.this) {
- enterInactiveStateLocked();
- }
}
}
};
@@ -487,7 +481,7 @@
mLocalPowerManager.setDeviceIdleMode(true);
try {
mNetworkPolicyManager.setDeviceIdleMode(true);
- mBatteryStats.noteDeviceIdleMode(true, false, false);
+ mBatteryStats.noteDeviceIdleMode(true, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
@@ -496,18 +490,19 @@
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
- mBatteryStats.noteDeviceIdleMode(false, false, false);
+ mBatteryStats.noteDeviceIdleMode(false, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
} break;
case MSG_REPORT_ACTIVE: {
- boolean fromMotion = msg.arg1 != 0;
+ String activeReason = (String)msg.obj;
+ int activeUid = msg.arg1;
boolean needBroadcast = msg.arg2 != 0;
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
- mBatteryStats.noteDeviceIdleMode(false, !fromMotion, fromMotion);
+ mBatteryStats.noteDeviceIdleMode(false, activeReason, activeUid);
} catch (RemoteException e) {
}
if (needBroadcast) {
@@ -578,6 +573,12 @@
}
}
+ @Override public void exitIdle(String reason) {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ exitIdleInternal(reason);
+ }
+
@Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
DeviceIdleController.this.dump(fd, pw, args);
}
@@ -604,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++) {
@@ -818,6 +821,12 @@
}
}
+ public void exitIdleInternal(String reason) {
+ synchronized (this) {
+ becomeActiveLocked(reason, Binder.getCallingUid());
+ }
+ }
+
void updateDisplayLocked() {
mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
// We consider any situation where the display is showing something to be it on,
@@ -830,7 +839,7 @@
becomeInactiveIfAppropriateLocked();
} else if (screenOn) {
mScreenOn = true;
- becomeActiveLocked("screen");
+ becomeActiveLocked("screen", Process.myUid());
}
}
@@ -841,21 +850,21 @@
becomeInactiveIfAppropriateLocked();
} else if (charging) {
mCharging = charging;
- becomeActiveLocked("charging");
+ becomeActiveLocked("charging", Process.myUid());
}
}
- void scheduleReportActiveLocked(boolean fromMotion) {
- Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, fromMotion ? 1 : 0,
- mState == STATE_IDLE ? 1 : 0);
+ void scheduleReportActiveLocked(String activeReason, int activeUid) {
+ Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid,
+ mState == STATE_IDLE ? 1 : 0, activeReason);
mHandler.sendMessage(msg);
}
- void becomeActiveLocked(String reason) {
- if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + reason);
+ void becomeActiveLocked(String activeReason, int activeUid) {
+ if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
if (mState != STATE_ACTIVE) {
- EventLogTags.writeDeviceIdle(STATE_ACTIVE, reason);
- scheduleReportActiveLocked(false);
+ EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
+ scheduleReportActiveLocked(activeReason, activeUid);
mState = STATE_ACTIVE;
mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
mNextIdlePendingDelay = 0;
@@ -867,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;
@@ -896,7 +905,7 @@
if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
// Whoops, there is an upcoming alarm. We don't actually want to go idle.
if (mState != STATE_ACTIVE) {
- becomeActiveLocked("alarm");
+ becomeActiveLocked("alarm", Process.myUid());
}
return;
}
@@ -954,7 +963,7 @@
// state to wait again for no motion. Note that we only monitor for significant
// motion after moving out of the inactive state, so no need to worry about that.
if (mState != STATE_ACTIVE) {
- scheduleReportActiveLocked(true);
+ scheduleReportActiveLocked("motion", Process.myUid());
mState = STATE_ACTIVE;
mInactiveTimeout = mConstants.MOTION_INACTIVE_TIMEOUT;
EventLogTags.writeDeviceIdle(mState, "motion");
@@ -1202,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) {
@@ -1238,22 +1251,27 @@
return;
} else if ("disable".equals(arg)) {
synchronized (this) {
- if (!mIdleDisabled) {
- mIdleDisabled = true;
- becomeActiveLocked("disabled");
+ if (mEnabled) {
+ mEnabled = false;
+ becomeActiveLocked("disabled", Process.myUid());
pw.println("Idle mode disabled");
}
}
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) {
@@ -1350,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 2f153a0..dbe8781 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
import android.annotation.NonNull;
+import android.content.pm.PackageManagerInternal;
import com.android.internal.content.PackageMonitor;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
@@ -31,6 +32,7 @@
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
+import com.android.server.pm.UserManagerService;
import com.android.server.statusbar.StatusBarManagerService;
import com.android.server.wm.WindowManagerService;
@@ -859,6 +861,38 @@
// mSettings should be created before buildInputMethodListLocked
mSettings = new InputMethodSettings(
mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+
+ // Let the package manager query which are the default imes
+ // as they get certain permissions granted by default.
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setImePackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ synchronized (mMethodMap) {
+ final int currentUserId = mSettings.getCurrentUserId();
+ // TODO: We are switching the current user id in the settings
+ // object to query it and then revert the user id. Ideally, we
+ // should call a API in settings with the user id as an argument.
+ mSettings.setCurrentUserId(userId);
+ List<InputMethodInfo> imes = mSettings
+ .getEnabledInputMethodListLocked();
+ String[] packageNames = null;
+ if (imes != null) {
+ final int imeCount = imes.size();
+ packageNames = new String[imeCount];
+ for (int i = 0; i < imeCount; i++) {
+ InputMethodInfo ime = imes.get(i);
+ packageNames[i] = ime.getPackageName();
+ }
+ }
+ mSettings.setCurrentUserId(currentUserId);
+ return packageNames;
+ }
+ }
+ });
+
updateCurrentProfileIds();
mFileManager = new InputMethodFileManager(mMethodMap, userId);
synchronized (mMethodMap) {
@@ -1009,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
@@ -1067,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 743aafb..cae060a 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.content.pm.PackageManagerInternal;
import com.android.internal.content.PackageMonitor;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
@@ -218,6 +219,19 @@
mContext = context;
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+ // Let the package manager query which are the default location
+ // providers as they get certain permissions granted by default.
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setLocationPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ return mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_locationProviderPackageNames);
+ }
+ });
+
if (D) Log.d(TAG, "Constructed");
// most startup is deferred until systemReady()
@@ -256,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);
@@ -1119,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;
}
@@ -1333,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);
@@ -1569,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,
@@ -1697,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 {
@@ -1706,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;
@@ -1780,7 +1820,6 @@
@Override
public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) {
- checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel());
checkPendingIntent(intent);
checkPackageName(packageName);
@@ -1802,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 {
@@ -1845,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);
}
@@ -1876,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);
}
@@ -2195,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..42794e7 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;
@@ -80,6 +79,7 @@
void setCredential(String credential, String savedCredential, int userId)
throws RemoteException;
byte[] toHash(String credential, int userId);
+ String adjustForKeystore(String credential);
}
public LockSettingsService(Context context) {
@@ -264,12 +264,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);
}
}
@@ -529,6 +529,11 @@
return LockPatternUtils.patternToHash(
LockPatternUtils.stringToPattern(pattern));
}
+
+ @Override
+ public String adjustForKeystore(String pattern) {
+ return LockPatternUtils.patternStringToBaseZero(pattern);
+ }
}
);
@@ -569,6 +574,11 @@
public byte[] toHash(String password, int userId) {
return mLockPatternUtils.passwordToHash(password, userId);
}
+
+ @Override
+ public String adjustForKeystore(String password) {
+ return password;
+ }
}
);
}
@@ -588,7 +598,7 @@
if (storedHash.version == CredentialHash.VERSION_LEGACY) {
byte[] hash = credentialUtil.toHash(credential, userId);
if (Arrays.equals(hash, storedHash.hash)) {
- unlockKeystore(credential, userId);
+ unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
// migrate credential to GateKeeper
credentialUtil.setCredential(credential, null, userId);
if (!hasChallenge) {
@@ -701,6 +711,15 @@
final KeyStore ks = KeyStore.getInstance();
ks.onUserRemoved(userId);
+
+ try {
+ final IGateKeeperService gk = getGateKeeperService();
+ if (gk != null) {
+ gk.clearSecureUserId(userId);
+ }
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "unable to clear GK secure user id");
+ }
}
private static final String[] VALID_SETTINGS = new String[] {
@@ -722,8 +741,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/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index f1d5aa3..1653db9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -16,12 +16,18 @@
package com.android.server;
+import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.os.AsyncTask;
import android.os.RecoverySystem;
+import android.os.storage.StorageManager;
import android.util.Log;
import android.util.Slog;
+import android.view.WindowManager;
+
+import com.android.internal.R;
import java.io.IOException;
@@ -39,6 +45,8 @@
final boolean shutdown = intent.getBooleanExtra("shutdown", false);
final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
+ final boolean wipeExternalStorage = intent.getBooleanExtra(
+ Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
Slog.w(TAG, "!!! FACTORY RESET !!!");
// The reboot call is blocking, so we need to do it on another thread.
@@ -55,6 +63,48 @@
}
}
};
- thr.start();
+
+ if (wipeExternalStorage) {
+ // thr will be started at the end of this task.
+ new WipeAdoptableDisksTask(context, thr).execute();
+ } else {
+ thr.start();
+ }
+ }
+
+ private class WipeAdoptableDisksTask extends AsyncTask<Void, Void, Void> {
+ private final Thread mChainedTask;
+ private final Context mContext;
+ private final ProgressDialog mProgressDialog;
+
+ public WipeAdoptableDisksTask(Context context, Thread chainedTask) {
+ mContext = context;
+ mChainedTask = chainedTask;
+ mProgressDialog = new ProgressDialog(context);
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mProgressDialog.setIndeterminate(true);
+ mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ mProgressDialog.setMessage(mContext.getText(R.string.progress_erasing));
+ mProgressDialog.show();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ Slog.w(TAG, "Wiping adoptable disks");
+ StorageManager sm = (StorageManager) mContext.getSystemService(
+ Context.STORAGE_SERVICE);
+ sm.wipeAdoptableDisks();
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ mProgressDialog.dismiss();
+ mChainedTask.start();
+ }
+
}
}
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 34dceed..45a7767 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -50,7 +50,9 @@
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -84,6 +86,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
@@ -259,6 +262,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";
@@ -674,13 +678,15 @@
}
private void handleSystemReady() {
- resetIfReadyAndConnected();
+ synchronized (mLock) {
+ resetIfReadyAndConnectedLocked();
+ }
// Start scheduling nominally-daily fstrim operations
MountServiceIdler.scheduleIdlePass(mContext);
}
- private void resetIfReadyAndConnected() {
+ private void resetIfReadyAndConnectedLocked() {
Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
+ ", mDaemonConnected=" + mDaemonConnected);
if (mSystemReady && mDaemonConnected) {
@@ -689,7 +695,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);
@@ -779,7 +785,9 @@
}
private void handleDaemonConnected() {
- resetIfReadyAndConnected();
+ synchronized (mLock) {
+ resetIfReadyAndConnectedLocked();
+ }
/*
* Now that we've done our initialization, release
@@ -900,10 +908,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;
@@ -1079,6 +1089,7 @@
case VolumeInfo.STATE_EJECTING:
case VolumeInfo.STATE_UNMOUNTED:
case VolumeInfo.STATE_UNMOUNTABLE:
+ case VolumeInfo.STATE_BAD_REMOVAL:
break;
default:
return false;
@@ -1091,13 +1102,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();
+ }
}
}
@@ -1107,6 +1126,7 @@
final Intent intent = new Intent(VolumeInfo.ACTION_VOLUME_STATE_CHANGED);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
+ intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.WRITE_MEDIA_STORAGE);
@@ -1347,6 +1367,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 +1377,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 +1513,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,18 +1597,19 @@
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.
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
}
- mCallbacks.notifyVolumeForgotten(fsUuid);
writeSettingsLocked();
}
}
@@ -1597,6 +1622,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();
@@ -1606,7 +1635,39 @@
}
writeSettingsLocked();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
+ }
+ }
+
+ 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 remountUid(int uid) {
+ enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+ waitForReady();
+
+ final int mountExternal = mPms.getMountExternalMode(uid);
+ final String mode;
+ if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
+ mode = "default";
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
+ mode = "read";
+ } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
+ mode = "write";
+ } else {
+ mode = "none";
+ }
+
+ try {
+ mConnector.execute("volume", "remount_uid", uid, mode);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.w(TAG, "Failed to remount UID " + uid + " as " + mode + ": " + e);
}
}
@@ -1621,7 +1682,7 @@
}
writeSettingsLocked();
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
}
}
@@ -1658,7 +1719,7 @@
Slog.d(TAG, "Skipping move to/from primary physical");
onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
- resetIfReadyAndConnected();
+ resetIfReadyAndConnectedLocked();
} else {
final VolumeInfo from = Preconditions.checkNotNull(
@@ -1992,7 +2053,7 @@
@Override
public void finishMediaUpdate() {
- if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("no permission to call finishMediaUpdate()");
}
if (mUnmountSignal != null) {
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%
rename from core/java/android/view/ViewAssistStructure.java
rename 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/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 5bce6eb..aace66c 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -18,6 +18,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.inputmethod.InputMethodUtils;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
@@ -61,9 +62,11 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -141,7 +144,7 @@
buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap, mSettings);
SpellCheckerInfo sci = getCurrentSpellChecker(null);
if (sci == null) {
- sci = findAvailSpellCheckerLocked(null, null);
+ sci = findAvailSpellCheckerLocked(null);
if (sci != null) {
// Set the current spell checker if there is one or more spell checkers
// available. In this case, "sci" is the first one in the available spell
@@ -190,7 +193,7 @@
change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
// Package modified
|| isPackageModified(packageName)) {
- sci = findAvailSpellCheckerLocked(null, packageName);
+ sci = findAvailSpellCheckerLocked(packageName);
if (sci != null) {
setCurrentSpellCheckerLocked(sci.getId());
}
@@ -331,8 +334,7 @@
mSpellCheckerBindGroups.clear();
}
- // TODO: find an appropriate spell checker for specified locale
- private SpellCheckerInfo findAvailSpellCheckerLocked(String locale, String prefPackage) {
+ private SpellCheckerInfo findAvailSpellCheckerLocked(String prefPackage) {
final int spellCheckersCount = mSpellCheckerList.size();
if (spellCheckersCount == 0) {
Slog.w(TAG, "no available spell checker services found");
@@ -349,6 +351,38 @@
}
}
}
+
+ // Look up a spell checker based on the system locale.
+ // TODO: Still there is a room to improve in the following logic: e.g., check if the package
+ // is pre-installed or not.
+ final Locale systemLocal = mContext.getResources().getConfiguration().locale;
+ final ArrayList<Locale> suitableLocales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(systemLocal);
+ if (DBG) {
+ Slog.w(TAG, "findAvailSpellCheckerLocked suitableLocales="
+ + Arrays.toString(suitableLocales.toArray(new Locale[suitableLocales.size()])));
+ }
+ final int localeCount = suitableLocales.size();
+ for (int localeIndex = 0; localeIndex < localeCount; ++localeIndex) {
+ final Locale locale = suitableLocales.get(localeIndex);
+ for (int spellCheckersIndex = 0; spellCheckersIndex < spellCheckersCount;
+ ++spellCheckersIndex) {
+ final SpellCheckerInfo info = mSpellCheckerList.get(spellCheckersIndex);
+ final int subtypeCount = info.getSubtypeCount();
+ for (int subtypeIndex = 0; subtypeIndex < subtypeCount; ++subtypeIndex) {
+ final SpellCheckerSubtype subtype = info.getSubtypeAt(subtypeIndex);
+ final Locale subtypeLocale = InputMethodUtils.constructLocaleFromString(
+ subtype.getLocale());
+ if (locale.equals(subtypeLocale)) {
+ // TODO: We may have more spell checkers that fall into this category.
+ // Ideally we should pick up the most suitable one instead of simply
+ // returning the first found one.
+ return info;
+ }
+ }
+ }
+ }
+
if (spellCheckersCount > 1) {
Slog.w(TAG, "more than one spell checker service found, picking first");
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 20f6f1c..30f4dce 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -47,7 +47,10 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
@@ -58,6 +61,8 @@
private static final boolean DEBUG = false;
private final LinkedList<Vibration> mVibrations;
+ private final LinkedList<VibrationInfo> mPreviousVibrations;
+ private final int mPreviousVibrationsLimit;
private Vibration mCurrentVibration;
private final WorkSource mTmpWorkSource = new WorkSource();
private final Handler mH = new Handler();
@@ -146,6 +151,47 @@
}
}
+ private static class VibrationInfo {
+ long timeout;
+ long startTime;
+ long[] pattern;
+ int repeat;
+ int usageHint;
+ int uid;
+ String opPkg;
+
+ public VibrationInfo(long timeout, long startTime, long[] pattern, int repeat,
+ int usageHint, int uid, String opPkg) {
+ this.timeout = timeout;
+ this.startTime = startTime;
+ this.pattern = pattern;
+ this.repeat = repeat;
+ this.usageHint = usageHint;
+ this.uid = uid;
+ this.opPkg = opPkg;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("timeout: ")
+ .append(timeout)
+ .append(", startTime: ")
+ .append(startTime)
+ .append(", pattern: ")
+ .append(Arrays.toString(pattern))
+ .append(", repeat: ")
+ .append(repeat)
+ .append(", usageHint: ")
+ .append(usageHint)
+ .append(", uid: ")
+ .append(uid)
+ .append(", opPkg: ")
+ .append(opPkg)
+ .toString();
+ }
+ }
+
VibratorService(Context context) {
// Reset the hardware to a default state, in case this is a runtime
// restart instead of a fresh boot.
@@ -161,7 +207,11 @@
mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
- mVibrations = new LinkedList<Vibration>();
+ mPreviousVibrationsLimit = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_previousVibrationsDumpLimit);
+
+ mVibrations = new LinkedList<>();
+ mPreviousVibrations = new LinkedList<>();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -252,6 +302,7 @@
removeVibrationLocked(token);
doCancelVibrateLocked();
mCurrentVibration = vib;
+ addToPreviousVibrationsLocked(vib);
startVibrationLocked(vib);
}
} finally {
@@ -315,6 +366,7 @@
mCurrentVibration = vib;
startVibrationLocked(vib);
}
+ addToPreviousVibrationsLocked(vib);
}
}
finally {
@@ -322,6 +374,14 @@
}
}
+ private void addToPreviousVibrationsLocked(Vibration vib) {
+ if (mPreviousVibrations.size() > mPreviousVibrationsLimit) {
+ mPreviousVibrations.removeFirst();
+ }
+ mPreviousVibrations.addLast(new VibratorService.VibrationInfo(vib.mTimeout, vib.mStartTime,
+ vib.mPattern, vib.mRepeat, vib.mUsageHint, vib.mUid, vib.mOpPkg));
+ }
+
@Override // Binder call
public void cancelVibrate(IBinder token) {
mContext.enforceCallingOrSelfPermission(
@@ -649,7 +709,6 @@
if (!mDone) {
// If this vibration finished naturally, start the next
// vibration.
- mVibrations.remove(mVibration);
unlinkVibration(mVibration);
startNextVibrationLocked();
}
@@ -685,4 +744,23 @@
}
}
};
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ pw.println("Permission Denial: can't dump vibrator service from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+ pw.println("Previous vibrations:");
+ synchronized (mVibrations) {
+ for (VibrationInfo info : mPreviousVibrations) {
+ pw.print(" ");
+ pw.println(info.toString());
+ }
+ }
+ }
}
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 c4f460e..959fd37 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,7 +18,9 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -142,6 +144,7 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.backup.IBackupManager;
+import android.app.admin.DevicePolicyManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ClipData;
@@ -676,9 +679,9 @@
final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
/**
- * Which uses have been started, so are allowed to run code.
+ * Which users have been started, so are allowed to run code.
*/
- final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
+ final SparseArray<UserState> mStartedUsers = new SparseArray<>();
/**
* LRU list of history of current users. Most recently current is at the end.
@@ -1781,15 +1784,15 @@
break;
}
case REPORT_USER_SWITCH_MSG: {
- dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case CONTINUE_USER_SWITCH_MSG: {
- continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case USER_SWITCH_TIMEOUT_MSG: {
- timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case IMMERSIVE_MODE_LOCK_MSG: {
@@ -2309,7 +2312,7 @@
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
// User 0 is the first and only user that runs at boot.
- mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
+ mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
@@ -2488,10 +2491,7 @@
synchronized(bstats) {
synchronized(mPidsSelfLocked) {
if (haveNewCpuStats) {
- final int perc = bstats.startAddingCpuLocked();
- if (perc >= 0) {
- int remainUTime = 0;
- int remainSTime = 0;
+ if (bstats.startAddingCpuLocked()) {
int totalUTime = 0;
int totalSTime = 0;
final int N = mProcessCpuTracker.countStats();
@@ -2501,10 +2501,6 @@
continue;
}
ProcessRecord pr = mPidsSelfLocked.get(st.pid);
- int otherUTime = (st.rel_utime*perc)/100;
- int otherSTime = (st.rel_stime*perc)/100;
- remainUTime += otherUTime;
- remainSTime += otherSTime;
totalUTime += st.rel_utime;
totalSTime += st.rel_stime;
if (pr != null) {
@@ -2513,8 +2509,7 @@
pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
pr.info.uid, pr.processName);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
pr.curCpuTime += st.rel_utime + st.rel_stime;
} else {
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
@@ -2522,8 +2517,7 @@
st.batteryStats = ps = bstats.getProcessStatsLocked(
bstats.mapUid(st.uid), st.name);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
}
final int userTime = mProcessCpuTracker.getLastUserTime();
@@ -2532,9 +2526,8 @@
final int irqTime = mProcessCpuTracker.getLastIrqTime();
final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
final int idleTime = mProcessCpuTracker.getLastIdleTime();
- bstats.finishAddingCpuLocked(perc, remainUTime,
- remainSTime, totalUTime, totalSTime, userTime, systemTime,
- iowaitTime, irqTime, softIrqTime, idleTime);
+ bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
+ systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
}
}
}
@@ -2754,13 +2747,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--;
@@ -3125,7 +3124,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");
}
@@ -3213,13 +3212,14 @@
int uid = app.uid;
int[] gids = null;
- int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+ int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
try {
checkTime(startTime, "startProcess: getting gids from package manager");
- permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
- app.userId);
+ final IPackageManager pm = AppGlobals.getPackageManager();
+ permGids = pm.getPackageGids(app.info.packageName, app.userId);
+ mountExternal = pm.getMountExternalMode(uid);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -3274,9 +3274,9 @@
debugFlags |= Zygote.DEBUG_ENABLE_JIT;
}
}
- String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
- if ("true".equals(genCFIDebugProperty)) {
- debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+ String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
+ if ("true".equals(genDebugInfoProperty)) {
+ debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
}
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
@@ -3587,8 +3587,23 @@
}
}
+ private boolean hasUsageStatsPermission(String callingPackage) {
+ final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
+ Binder.getCallingUid(), callingPackage);
+ if (mode == AppOpsManager.MODE_DEFAULT) {
+ return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ return mode == AppOpsManager.MODE_ALLOWED;
+ }
+
@Override
- public int getPackageProcessState(String packageName) {
+ public int getPackageProcessState(String packageName, String callingPackage) {
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
+ "getPackageProcessState");
+ }
+
int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
synchronized (this) {
for (int i=mLruProcesses.size()-1; i>=0; i--) {
@@ -4611,7 +4626,7 @@
if (!fromBinderDied) {
Process.killProcessQuiet(pid);
}
- Process.killProcessGroup(app.info.uid, pid);
+ killProcessGroup(app.info.uid, pid);
app.killed = true;
}
@@ -5932,7 +5947,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();
@@ -6313,9 +6328,9 @@
SystemProperties.set("dev.bootcomplete", "1");
}
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
- if (uss.mState == UserStartedState.STATE_BOOTING) {
- uss.mState = UserStartedState.STATE_RUNNING;
+ UserState uss = mStartedUsers.valueAt(i);
+ if (uss.mState == UserState.STATE_BOOTING) {
+ uss.mState = UserState.STATE_RUNNING;
final int userId = mStartedUsers.keyAt(i);
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -8278,7 +8293,7 @@
try {
if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
allowed = true;
- Slog.w(TAG, caller + ": caller " + callingUid
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ " is using old GET_TASKS but privileged; allowing");
}
} catch (RemoteException e) {
@@ -8286,7 +8301,7 @@
}
}
if (!allowed) {
- Slog.w(TAG, caller + ": caller " + callingUid
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ " does not hold REAL_GET_TASKS; limiting output");
}
return allowed;
@@ -9442,6 +9457,7 @@
}
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
boolean success = updateOomAdjLocked(cpr.proc);
+ maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
// NOTE: there is still a race here where a signal could be
@@ -9831,6 +9847,8 @@
dst.notifyAll();
}
updateOomAdjLocked(r);
+ maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
+ src.info.authority);
}
}
@@ -10674,6 +10692,21 @@
}
@Override
+ public boolean isScreenCaptureAllowedOnCurrentActivity() {
+ int userId = mCurrentUserId;
+ synchronized (this) {
+ ActivityRecord activity = getFocusedStack().topActivity();
+ if (activity == null) {
+ return false;
+ }
+ userId = activity.userId;
+ }
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
+ }
+
+ @Override
public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
@@ -10778,15 +10811,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);
}
}
@@ -12397,7 +12436,7 @@
} else {
// Huh.
Process.killProcess(pid);
- Process.killProcessGroup(uid, pid);
+ killProcessGroup(uid, pid);
}
}
return;
@@ -13343,7 +13382,7 @@
needSep = false;
pw.println(" mStartedUsers:");
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
+ UserState uss = mStartedUsers.valueAt(i);
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
pw.print(": "); uss.dump("", pw);
}
@@ -18615,6 +18654,22 @@
uidRec.pendingChange.processState = uidRec.setProcState;
}
+ private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
+ String authority) {
+ if (app == null) return;
+ if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
+ UserState userState = mStartedUsers.get(app.userId);
+ if (userState == null) return;
+ final long now = SystemClock.elapsedRealtime();
+ Long lastReported = userState.mProviderLastReportedFg.get(authority);
+ if (lastReported == null || lastReported < now - 60 * 1000L) {
+ mUsageStatsService.reportContentProviderUsage(
+ authority, providerPkgName, app.userId);
+ userState.mProviderLastReportedFg.put(authority, now);
+ }
+ }
+ }
+
private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
if (DEBUG_USAGE_STATS) {
Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
@@ -19602,7 +19657,7 @@
// If the user we are switching to is not currently started, then
// we need to start it now.
if (mStartedUsers.get(userId) == null) {
- mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
+ mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
updateStartedUserArrayLocked();
needStart = true;
}
@@ -19627,26 +19682,26 @@
mUserLru.add(currentUserIdInt);
}
- final UserStartedState uss = mStartedUsers.get(userId);
+ final UserState uss = mStartedUsers.get(userId);
// Make sure user is in the started state. If it is currently
// stopping, we need to knock that off.
- if (uss.mState == UserStartedState.STATE_STOPPING) {
+ if (uss.mState == UserState.STATE_STOPPING) {
// If we are stopping, we haven't sent ACTION_SHUTDOWN,
// so we can just fairly silently bring the user back from
// the almost-dead.
- uss.mState = UserStartedState.STATE_RUNNING;
+ uss.mState = UserState.STATE_RUNNING;
updateStartedUserArrayLocked();
needStart = true;
- } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
+ } else if (uss.mState == UserState.STATE_SHUTDOWN) {
// This means ACTION_SHUTDOWN has been sent, so we will
// need to treat this as a new boot of the user.
- uss.mState = UserStartedState.STATE_BOOTING;
+ uss.mState = UserState.STATE_BOOTING;
updateStartedUserArrayLocked();
needStart = true;
}
- if (uss.mState == UserStartedState.STATE_BOOTING) {
+ if (uss.mState == UserState.STATE_BOOTING) {
// Booting up a new user, need to tell system services about it.
// Note that this is on the same handler as scheduling of broadcasts,
// which is important because it needs to go first.
@@ -19784,7 +19839,7 @@
}
}
- void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
+ void dispatchUserSwitch(final UserState uss, final int oldUserId,
final int newUserId) {
final int N = mUserSwitchObservers.beginBroadcast();
if (N > 0) {
@@ -19821,21 +19876,21 @@
mUserSwitchObservers.finishBroadcast();
}
- void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
+ void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
synchronized (this) {
Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
}
}
- void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
+ void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
mCurUserSwitchCallback = null;
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
oldUserId, newUserId, uss));
}
- void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
+ void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
synchronized (this) {
if (foreground) {
moveUserToForeground(uss, oldUserId, newUserId);
@@ -19845,7 +19900,7 @@
completeSwitchAndInitalize(uss, newUserId, true, false);
}
- void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
+ void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
if (homeInFront) {
startHomeActivityLocked(newUserId, "moveUserToFroreground");
@@ -19857,11 +19912,11 @@
sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
}
- void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
+ void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
completeSwitchAndInitalize(uss, newUserId, false, true);
}
- void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
+ void completeSwitchAndInitalize(UserState uss, int newUserId,
boolean clearInitializing, boolean clearSwitching) {
boolean unfrozen = false;
synchronized (this) {
@@ -19898,10 +19953,10 @@
final int num = mUserLru.size();
for (int i = 0; i < num; i++) {
Integer oldUserId = mUserLru.get(i);
- UserStartedState oldUss = mStartedUsers.get(oldUserId);
+ UserState oldUss = mStartedUsers.get(oldUserId);
if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
- || oldUss.mState == UserStartedState.STATE_STOPPING
- || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+ || oldUss.mState == UserState.STATE_STOPPING
+ || oldUss.mState == UserState.STATE_SHUTDOWN) {
continue;
}
UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
@@ -19942,11 +19997,11 @@
}
}
- void finishUserBoot(UserStartedState uss) {
+ void finishUserBoot(UserState uss) {
synchronized (this) {
- if (uss.mState == UserStartedState.STATE_BOOTING
+ if (uss.mState == UserState.STATE_BOOTING
&& mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
- uss.mState = UserStartedState.STATE_RUNNING;
+ uss.mState = UserState.STATE_RUNNING;
final int userId = uss.mHandle.getIdentifier();
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -19959,7 +20014,7 @@
}
}
- void finishUserSwitch(UserStartedState uss) {
+ void finishUserSwitch(UserState uss) {
synchronized (this) {
finishUserBoot(uss);
@@ -19969,15 +20024,15 @@
int i = 0;
while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
Integer oldUserId = mUserLru.get(i);
- UserStartedState oldUss = mStartedUsers.get(oldUserId);
+ UserState oldUss = mStartedUsers.get(oldUserId);
if (oldUss == null) {
// Shouldn't happen, but be sane if it does.
mUserLru.remove(i);
num--;
continue;
}
- if (oldUss.mState == UserStartedState.STATE_STOPPING
- || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+ if (oldUss.mState == UserState.STATE_STOPPING
+ || oldUss.mState == UserState.STATE_SHUTDOWN) {
// This user is already stopping, doesn't count.
num--;
i++;
@@ -20022,7 +20077,7 @@
return ActivityManager.USER_OP_IS_CURRENT;
}
- final UserStartedState uss = mStartedUsers.get(userId);
+ final UserState uss = mStartedUsers.get(userId);
if (uss == null) {
// User is not started, nothing to do... but we do need to
// callback if requested.
@@ -20044,9 +20099,9 @@
uss.mStopCallbacks.add(callback);
}
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
- uss.mState = UserStartedState.STATE_STOPPING;
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
+ uss.mState = UserState.STATE_STOPPING;
updateStartedUserArrayLocked();
long ident = Binder.clearCallingIdentity();
@@ -20074,11 +20129,11 @@
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// On to the next.
synchronized (ActivityManagerService.this) {
- if (uss.mState != UserStartedState.STATE_STOPPING) {
+ if (uss.mState != UserState.STATE_STOPPING) {
// Whoops, we are being started back up. Abort, abort!
return;
}
- uss.mState = UserStartedState.STATE_SHUTDOWN;
+ uss.mState = UserState.STATE_SHUTDOWN;
}
mBatteryStatsService.noteEvent(
BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
@@ -20102,7 +20157,7 @@
return ActivityManager.USER_OP_SUCCESS;
}
- void finishUserStop(UserStartedState uss) {
+ void finishUserStop(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
boolean stopped;
ArrayList<IStopUserCallback> callbacks;
@@ -20110,7 +20165,7 @@
callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
if (mStartedUsers.get(userId) != uss) {
stopped = false;
- } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ } else if (uss.mState != UserState.STATE_SHUTDOWN) {
stopped = false;
} else {
stopped = true;
@@ -20184,15 +20239,15 @@
}
boolean isUserRunningLocked(int userId, boolean orStopped) {
- UserStartedState state = mStartedUsers.get(userId);
+ UserState state = mStartedUsers.get(userId);
if (state == null) {
return false;
}
if (orStopped) {
return true;
}
- return state.mState != UserStartedState.STATE_STOPPING
- && state.mState != UserStartedState.STATE_SHUTDOWN;
+ return state.mState != UserState.STATE_STOPPING
+ && state.mState != UserState.STATE_SHUTDOWN;
}
@Override
@@ -20214,19 +20269,19 @@
private void updateStartedUserArrayLocked() {
int num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
+ UserState uss = mStartedUsers.valueAt(i);
// This list does not include stopping users.
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
num++;
}
}
mStartedUserArray = new int[num];
num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ UserState uss = mStartedUsers.valueAt(i);
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
mStartedUserArray[num] = mStartedUsers.keyAt(i);
num++;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9e33f2a..4ce5c7e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -25,7 +25,6 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.server.am.ActivityManagerDebugConfig.*;
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
@@ -39,11 +38,13 @@
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
+import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
import android.app.AppGlobals;
+import android.app.AppOpsManager;
import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IActivityManager;
@@ -62,6 +63,7 @@
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
@@ -90,9 +92,11 @@
import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.service.voice.IVoiceInteractionSession;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Slog;
@@ -108,6 +112,7 @@
import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.TransferPipe;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.am.ActivityStack.ActivityState;
@@ -170,6 +175,25 @@
private static final String LOCK_TASK_TAG = "Lock-to-App";
+ // Activity actions an app cannot start if it uses a permission which is not granted.
+ private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
+ new ArrayMap<>();
+ static {
+ ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
+ Manifest.permission.CAMERA);
+ ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
+ Manifest.permission.CAMERA);
+ ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
+ Manifest.permission.CALL_PHONE);
+ }
+
+ /** Action not restricted for the calling package. */
+ private static final int ACTION_RESTRICTION_NONE = 0;
+ /** Action restricted for the calling package by not granting a used permission. */
+ private static final int ACTION_RESTRICTION_PERMISSION = 1;
+ /** Action restricted for the calling package by not allowing a used permission's app op. */
+ private static final int ACTION_RESTRICTION_APPOP = 2;
+
/** Status Bar Service **/
private IBinder mToken = new Binder();
private IStatusBarService mStatusBarService;
@@ -233,10 +257,10 @@
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
/** Used on user changes */
- final ArrayList<UserStartedState> mStartingUsers = new ArrayList<>();
+ final ArrayList<UserState> mStartingUsers = new ArrayList<>();
/** Used to queue up any background users being started */
- final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<>();
+ final ArrayList<UserState> mStartingBackgroundUsers = new ArrayList<>();
/** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
* is being brought in front of us. */
@@ -883,8 +907,18 @@
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
- startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
- 0, 0, 0, null, false, null, null, null);
+ startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
+ null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
+ null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
+ null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
+ 0 /* startFlags */, null /* options */, false /* componentSpecified */,
+ null /* outActivity */, null /* container */, null /* inTask */);
+ if (inResumeTopActivity) {
+ // If we are in resume section already, home activity will be initialized, but not
+ // resumed (to avoid recursive resume) and will stay that way until something pokes it
+ // again. We need to schedule another resume.
+ scheduleResumeTopActivities();
+ }
}
final int startActivityMayWait(IApplicationThread caller, int callingUid,
@@ -1509,14 +1543,23 @@
START_ANY_ACTIVITY, callingPid, callingUid);
final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);
- if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
+ final int actionRestriction = getActionRestrictionForCallingPackage(
+ intent.getAction(), callingPackage, callingPid, callingUid);
+
+ if (startAnyPerm != PERMISSION_GRANTED && (componentPerm != PERMISSION_GRANTED
+ || actionRestriction == ACTION_RESTRICTION_PERMISSION)) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
String msg;
- if (!aInfo.exported) {
+ if (actionRestriction == ACTION_RESTRICTION_PERMISSION) {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")" + " with revoked permission "
+ + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
+ } else if (!aInfo.exported) {
msg = "Permission Denial: starting " + intent.toString()
+ " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
@@ -1531,7 +1574,19 @@
throw new SecurityException(msg);
}
- boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
+ boolean abort = false;
+
+ if (startAnyPerm != PERMISSION_GRANTED
+ && actionRestriction == ACTION_RESTRICTION_APPOP) {
+ String msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")"
+ + " requires " + aInfo.permission;
+ Slog.w(TAG, msg);
+ abort = true;
+ }
+
+ abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
if (mService.mController != null) {
@@ -1609,6 +1664,48 @@
return err;
}
+ private int getActionRestrictionForCallingPackage(String action,
+ String callingPackage, int callingPid, int callingUid) {
+ if (action == null) {
+ return ACTION_RESTRICTION_NONE;
+ }
+
+ String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
+ if (permission == null) {
+ return ACTION_RESTRICTION_NONE;
+ }
+
+ final PackageInfo packageInfo;
+ try {
+ packageInfo = mService.mContext.getPackageManager()
+ .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.i(TAG, "Cannot find package info for " + callingPackage);
+ return ACTION_RESTRICTION_NONE;
+ }
+
+ if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
+ return ACTION_RESTRICTION_NONE;
+ }
+
+ if (mService.checkPermission(permission, callingPid, callingUid) ==
+ PackageManager.PERMISSION_DENIED) {
+ return ACTION_RESTRICTION_PERMISSION;
+ }
+
+ final int opCode = AppOpsManager.permissionToOpCode(permission);
+ if (opCode == AppOpsManager.OP_NONE) {
+ return ACTION_RESTRICTION_NONE;
+ }
+
+ if (mService.mAppOpsService.noteOperation(opCode, callingUid,
+ callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ return ACTION_RESTRICTION_APPOP;
+ }
+
+ return ACTION_RESTRICTION_NONE;
+ }
+
ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
final TaskRecord task = r.task;
@@ -1915,7 +2012,12 @@
ActivityRecord intentActivity = !launchSingleInstance ?
findTaskLocked(r) : findActivityLocked(intent, r.info);
if (intentActivity != null) {
- if (isLockTaskModeViolation(intentActivity.task)) {
+ // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
+ // but still needs to be a lock task mode violation since the task gets
+ // cleared out and the device would otherwise leave the locked task.
+ if (isLockTaskModeViolation(intentActivity.task,
+ (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+ == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
showLockTaskToast();
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
@@ -2371,7 +2473,7 @@
ArrayList<ActivityRecord> stops = null;
ArrayList<ActivityRecord> finishes = null;
- ArrayList<UserStartedState> startingUsers = null;
+ ArrayList<UserState> startingUsers = null;
int NS = 0;
int NF = 0;
boolean booting = false;
@@ -2468,7 +2570,7 @@
}
// Complete starting up of background users
if (mStartingBackgroundUsers.size() > 0) {
- startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
+ startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
mStartingBackgroundUsers.clear();
for (int i = 0; i < startingUsers.size(); i++) {
mService.finishUserBoot(startingUsers.get(i));
@@ -3230,7 +3332,7 @@
}
}
- boolean switchUserLocked(int userId, UserStartedState uss) {
+ boolean switchUserLocked(int userId, UserState uss) {
mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
mCurrentUser = userId;
@@ -3271,7 +3373,7 @@
* @param userId The user being started in the background
* @param uss The state object for the user.
*/
- public void startBackgroundUserLocked(int userId, UserStartedState uss) {
+ public void startBackgroundUserLocked(int userId, UserState uss) {
mStartingBackgroundUsers.add(uss);
}
@@ -3780,7 +3882,11 @@
}
boolean isLockTaskModeViolation(TaskRecord task) {
- if (getLockedTaskLocked() == task) {
+ return isLockTaskModeViolation(task, false);
+ }
+
+ boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
+ if (getLockedTaskLocked() == task && !isNewClearTask) {
return false;
}
final int lockTaskAuth = task.mLockTaskAuth;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c973386..6cc1b11 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -38,10 +38,12 @@
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;
+import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsHelper;
@@ -64,16 +66,22 @@
implements PowerManagerInternal.LowPowerModeListener {
static final String TAG = "BatteryStatsService";
- private boolean mFirstExternalStatsUpdate = true;
static IBatteryStats sService;
final BatteryStatsImpl mStats;
final BatteryStatsHandler mHandler;
Context mContext;
PowerManagerInternal mPowerManagerInternal;
+ final int UPDATE_CPU = 0x01;
+ final int UPDATE_WIFI = 0x02;
+ final int UPDATE_RADIO = 0x04;
+ final int UPDATE_BT = 0x08;
+ final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
+
class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
public static final int MSG_SYNC_EXTERNAL_STATS = 1;
public static final int MSG_WRITE_TO_DISK = 2;
+ private int mUpdateFlags = 0;
public BatteryStatsHandler(Looper looper) {
super(looper);
@@ -83,11 +91,17 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SYNC_EXTERNAL_STATS:
- updateExternalStats((String)msg.obj, false);
+ final int updateFlags;
+ synchronized (this) {
+ removeMessages(MSG_SYNC_EXTERNAL_STATS);
+ updateFlags = mUpdateFlags;
+ mUpdateFlags = 0;
+ }
+ updateExternalStats((String)msg.obj, updateFlags);
break;
case MSG_WRITE_TO_DISK:
- updateExternalStats("write", true);
+ updateExternalStats("write", UPDATE_ALL);
synchronized (mStats) {
mStats.writeAsyncLocked();
}
@@ -97,9 +111,20 @@
@Override
public void scheduleSync(String reason) {
- if (!hasMessages(MSG_SYNC_EXTERNAL_STATS)) {
- Message msg = Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason);
- sendMessage(msg);
+ scheduleSyncImpl(reason, UPDATE_ALL);
+ }
+
+ @Override
+ public void scheduleWifiSync(String reason) {
+ scheduleSyncImpl(reason, UPDATE_WIFI);
+ }
+
+ private void scheduleSyncImpl(String reason, int updateFlags) {
+ synchronized (this) {
+ if (mUpdateFlags == 0) {
+ sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason));
+ }
+ mUpdateFlags |= updateFlags;
}
}
}
@@ -137,7 +162,7 @@
public void shutdown() {
Slog.w("BatteryStats", "Writing battery stats before shutdown...");
- updateExternalStats("shutdown", true);
+ updateExternalStats("shutdown", UPDATE_ALL);
synchronized (mStats) {
mStats.shutdownLocked();
}
@@ -237,7 +262,7 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -252,7 +277,7 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -603,8 +628,13 @@
// There was a change in WiFi power state.
// Collect data now for the past activity.
- mHandler.scheduleSync("wifi-data");
synchronized (mStats) {
+ if (mStats.isOnBattery()) {
+ 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);
}
}
@@ -767,10 +797,10 @@
}
@Override
- public void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion) {
+ public void noteDeviceIdleMode(boolean enabled, String activeReason, int activeUid) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteDeviceIdleModeLocked(enabled, fromActive, fromMotion);
+ mStats.noteDeviceIdleModeLocked(enabled, activeReason, activeUid);
}
}
@@ -807,7 +837,7 @@
// Sync external stats first as the battery has changed states. If we don't sync
// immediately here, we may not collect the relevant data later.
- updateExternalStats("battery-state", false);
+ updateExternalStats("battery-state", UPDATE_ALL);
synchronized (mStats) {
mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
}
@@ -834,8 +864,7 @@
}
final class WakeupReasonThread extends Thread {
- final int[] mIrqs = new int[32];
- final String[] mReasons = new String[32];
+ final String[] mReason = new String[1];
WakeupReasonThread() {
super("BatteryStats_wakeupReason");
@@ -846,12 +875,11 @@
try {
int num;
- while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
+ while ((num = nativeWaitWakeup(mReason)) >= 0) {
synchronized (mStats) {
+ // num will be either 0 or 1.
if (num > 0) {
- for (int i=0; i<num; i++) {
- mStats.noteWakeupReasonLocked(mReasons[i]);
- }
+ mStats.noteWakeupReasonLocked(mReason[0]);
} else {
mStats.noteWakeupReasonLocked("unknown");
}
@@ -863,7 +891,7 @@
}
}
- private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
+ private static native int nativeWaitWakeup(String[] outReason);
private void dumpHelp(PrintWriter pw) {
pw.println("Battery stats (batterystats) dump options:");
@@ -961,9 +989,9 @@
pw.println("Battery stats reset.");
noOutput = true;
}
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} else if ("--write".equals(arg)) {
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
synchronized (mStats) {
mStats.writeSyncLocked();
pw.println("Battery stats written.");
@@ -1027,7 +1055,7 @@
flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
}
// Fetch data from external sources and update the BatteryStatsImpl object with them.
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1119,6 +1147,12 @@
return null;
}
+ final long timePeriodMs = info.mTimestamp - mLastInfo.mTimestamp;
+ final long lastIdleMs = mLastInfo.mControllerIdleTimeMs;
+ final long lastTxMs = mLastInfo.mControllerTxTimeMs;
+ final long lastRxMs = mLastInfo.mControllerRxTimeMs;
+ final long lastEnergy = mLastInfo.mControllerEnergyUsed;
+
// We will modify the last info object to be the delta, and store the new
// WifiActivityEnergyInfo object as our last one.
final WifiActivityEnergyInfo result = mLastInfo;
@@ -1126,19 +1160,16 @@
result.mStackState = info.getStackState();
// These times seem to be the most reliable.
- result.mControllerTxTimeMs =
- info.mControllerTxTimeMs - mLastInfo.mControllerTxTimeMs;
- result.mControllerRxTimeMs =
- info.mControllerRxTimeMs - mLastInfo.mControllerRxTimeMs;
+ result.mControllerTxTimeMs = info.mControllerTxTimeMs - lastTxMs;
+ result.mControllerRxTimeMs = info.mControllerRxTimeMs - lastRxMs;
// WiFi calculates the idle time as a difference from the on time and the various
// Rx + Tx times. There seems to be some missing time there because this sometimes
// becomes negative. Just cap it at 0 and move on.
// b/21613534
- result.mControllerIdleTimeMs =
- Math.max(0, info.mControllerIdleTimeMs - mLastInfo.mControllerIdleTimeMs);
+ result.mControllerIdleTimeMs = Math.max(0, info.mControllerIdleTimeMs - lastIdleMs);
result.mControllerEnergyUsed =
- Math.max(0, info.mControllerEnergyUsed - mLastInfo.mControllerEnergyUsed);
+ Math.max(0, info.mControllerEnergyUsed - lastEnergy);
if (result.mControllerTxTimeMs < 0 ||
result.mControllerRxTimeMs < 0) {
@@ -1151,6 +1182,34 @@
Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
}
+
+ final long totalTimeMs = result.mControllerIdleTimeMs + result.mControllerRxTimeMs +
+ result.mControllerTxTimeMs;
+ if (totalTimeMs > timePeriodMs) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Total time ");
+ TimeUtils.formatDuration(totalTimeMs, sb);
+ sb.append(" is longer than sample period ");
+ TimeUtils.formatDuration(timePeriodMs, sb);
+ sb.append(".\n");
+ sb.append("Previous WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(lastIdleMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(lastRxMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(lastTxMs, sb);
+ sb.append(" e=").append(lastEnergy);
+ sb.append("\n");
+ sb.append("Current WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(info.mControllerIdleTimeMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(info.mControllerRxTimeMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(info.mControllerTxTimeMs, sb);
+ sb.append(" e=").append(info.mControllerEnergyUsed);
+ Slog.wtf(TAG, sb.toString());
+ }
+
mLastInfo = info;
return result;
}
@@ -1184,15 +1243,12 @@
* We first grab a lock specific to this method, then once all the data has been collected,
* we grab the mStats lock and update the data.
*
- * TODO(adamlesinski): When we start distributing bluetooth data to apps, we'll want to
- * separate these external stats so that they can be collected individually and on different
- * intervals.
- *
* @param reason The reason why this collection was requested. Useful for debugging.
- * @param force If false, some stats may decide not to be collected for efficiency as their
- * results aren't needed immediately. When true, collect all stats unconditionally.
+ * @param updateFlags Which external stats to update. Can be a combination of
+ * {@link #UPDATE_CPU}, {@link #UPDATE_RADIO}, {@link #UPDATE_WIFI},
+ * and {@link #UPDATE_BT}.
*/
- void updateExternalStats(String reason, boolean force) {
+ void updateExternalStats(final String reason, final int updateFlags) {
synchronized (mExternalStatsLock) {
if (mContext == null) {
// We haven't started yet (which means the BatteryStatsImpl object has
@@ -1200,34 +1256,46 @@
return;
}
- final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
- final BluetoothActivityEnergyInfo bluetoothEnergyInfo;
- if (force) {
+ if (BatteryStatsImpl.DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating external stats: reason=" + reason);
+ }
+
+ WifiActivityEnergyInfo wifiEnergyInfo = null;
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ wifiEnergyInfo = pullWifiEnergyInfoLocked();
+ }
+
+ BluetoothActivityEnergyInfo bluetoothEnergyInfo = null;
+ if ((updateFlags & UPDATE_BT) != 0) {
// We only pull bluetooth stats when we have to, as we are not distributing its
// use amongst apps and the sampling frequency does not matter.
bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
- } else {
- bluetoothEnergyInfo = null;
}
synchronized (mStats) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
if (mStats.mRecordAllHistory) {
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- final long uptime = SystemClock.uptimeMillis();
mStats.addHistoryEventLocked(elapsedRealtime, uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
}
- mStats.updateCpuTimeLocked(mFirstExternalStatsUpdate);
- mStats.updateKernelWakelocksLocked();
- mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
- mStats.updateWifiStateLocked(wifiEnergyInfo);
- mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
- }
- if (mFirstExternalStatsUpdate) {
- // We have read the stats for the first time, which means we have a baseline
- // from which to calculate delta.
- mFirstExternalStatsUpdate = false;
+ if ((updateFlags & UPDATE_CPU) != 0) {
+ mStats.updateCpuTimeLocked();
+ mStats.updateKernelWakelocksLocked();
+ }
+
+ if ((updateFlags & UPDATE_RADIO) != 0) {
+ mStats.updateMobileRadioStateLocked(elapsedRealtime);
+ }
+
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ mStats.updateWifiStateLocked(wifiEnergyInfo);
+ }
+
+ if ((updateFlags & UPDATE_BT) != 0) {
+ mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
+ }
}
}
}
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/am/UserStartedState.java b/services/core/java/com/android/server/am/UserState.java
similarity index 85%
rename from services/core/java/com/android/server/am/UserStartedState.java
rename to services/core/java/com/android/server/am/UserState.java
index d3e73d5..b3d82bc 100644
--- a/services/core/java/com/android/server/am/UserStartedState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -21,8 +21,9 @@
import android.app.IStopUserCallback;
import android.os.UserHandle;
+import android.util.ArrayMap;
-public final class UserStartedState {
+public final class UserState {
// User is first coming up.
public final static int STATE_BOOTING = 0;
// User is in the normal running state.
@@ -40,7 +41,13 @@
public boolean switching;
public boolean initializing;
- public UserStartedState(UserHandle handle, boolean initial) {
+ /**
+ * The last time that a provider was reported to usage stats as being brought to important
+ * foreground procstate.
+ */
+ public final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>();
+
+ public UserState(UserHandle handle, boolean initial) {
mHandle = handle;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d39b25f..dd4111d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1542,11 +1542,7 @@
// UI update and Broadcast Intent
private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
- if (!isPlatformVoice() && (streamType == AudioSystem.STREAM_RING)) {
- streamType = AudioSystem.STREAM_NOTIFICATION;
- } else {
- streamType = mStreamVolumeAlias[streamType];
- }
+ streamType = mStreamVolumeAlias[streamType];
if (streamType == AudioSystem.STREAM_MUSIC) {
flags = updateFlagsForSystemAudio(flags);
@@ -3103,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
@@ -3792,6 +3791,8 @@
// fire changed intents for all streams
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
+ mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
+ mStreamVolumeAlias[mStreamType]);
sendBroadcastToAll(mVolumeChanged);
}
return changed;
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 4ccb5ad..f72b598 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -46,10 +46,12 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.speech.RecognizerIntent;
@@ -1086,6 +1088,14 @@
voiceIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
Log.i(TAG, "voice-based interactions: about to use ACTION_WEB_SEARCH");
} else {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE,
isLocked && mKeyguardManager.isKeyguardSecure());
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 eac748f..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;
@@ -106,8 +110,16 @@
networkMisc = misc;
}
- public void addRequest(NetworkRequest networkRequest) {
+ /**
+ * Add {@code networkRequest} to this network as it's satisfied by this network.
+ * NOTE: This function must only be called on ConnectivityService's main thread.
+ * @return true if {@code networkRequest} was added or false if {@code networkRequest} was
+ * already present.
+ */
+ public boolean addRequest(NetworkRequest networkRequest) {
+ if (networkRequests.get(networkRequest.requestId) == networkRequest) return false;
networkRequests.put(networkRequest.requestId, networkRequest);
+ return true;
}
// Does this network satisfy request?
@@ -166,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/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index 5d56d4a..74ba404 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -113,18 +113,18 @@
public void recordSuccess(String msg) {
maybeFixupTimes();
+ result = SUCCEEDED + ": " + msg;
if (mCountDownLatch != null) {
mCountDownLatch.countDown();
}
- result = SUCCEEDED + ": " + msg;
}
public void recordFailure(String msg) {
maybeFixupTimes();
+ result = FAILED + ": " + msg;
if (mCountDownLatch != null) {
mCountDownLatch.countDown();
}
- result = FAILED + ": " + msg;
}
private void maybeFixupTimes() {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index fc50e2c..310e361 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -47,6 +47,8 @@
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -178,6 +180,13 @@
*/
private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11;
+ /**
+ * Retest network to see if captive portal is still in place.
+ * arg1 = UID responsible for requesting this reeval. Will be billed for data.
+ * 0 indicates self-initiated, so nobody to blame.
+ */
+ private static final int CMD_CAPTIVE_PORTAL_RECHECK = BASE + 12;
+
private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
// Default to 30s linger time-out. Modifyable only for testing.
private static int DEFAULT_LINGER_DELAY_MS = 30000;
@@ -194,6 +203,8 @@
private int mUidResponsibleForReeval = INVALID_UID;
// Stop blaming UID that requested re-evaluation after this many attempts.
private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
+ // Delay between reevaluations once a captive portal has been found.
+ private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10*60*1000;
private final Context mContext;
private final Handler mConnectivityServiceHandler;
@@ -223,6 +234,8 @@
private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
private String mCaptivePortalLoggedInResponseToken = null;
+ private final LocalLog validationLogs = new LocalLog(20); // 20 lines
+
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
// Add suffix indicating which NetworkMonitor we're talking about.
@@ -263,6 +276,15 @@
Log.d(TAG + "/" + mNetworkAgentInfo.name(), s);
}
+ private void validationLog(String s) {
+ if (DBG) log(s);
+ validationLogs.log(s);
+ }
+
+ public ReadOnlyLocalLog getValidationLogs() {
+ return validationLogs.readOnlyLocalLog();
+ }
+
// DefaultState is the parent of all States. It exists only to handle CMD_* messages but
// does not entail any real state (hence no enter() or exit() routines).
private class DefaultState extends State {
@@ -287,6 +309,7 @@
quit();
return HANDLED;
case CMD_FORCE_REEVALUATION:
+ case CMD_CAPTIVE_PORTAL_RECHECK:
if (DBG) log("Forcing reevaluation");
mUidResponsibleForReeval = message.arg1;
transitionTo(mEvaluatingState);
@@ -517,6 +540,9 @@
mNetworkAgentInfo.network.netId,
mLaunchCaptivePortalAppBroadcastReceiver.getPendingIntent());
mConnectivityServiceHandler.sendMessage(message);
+ // Retest for captive portal occasionally.
+ sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
+ CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
}
@Override
@@ -524,6 +550,11 @@
if (DBG) log(getName() + message.toString());
return NOT_HANDLED;
}
+
+ @Override
+ public void exit() {
+ removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
+ }
}
// Being in the LingeringState State indicates a Network's validated bit is true and it once
@@ -631,10 +662,8 @@
fetchPac = true;
}
}
- if (DBG) {
- log("Checking " + url.toString() + " on " +
- mNetworkAgentInfo.networkInfo.getExtraInfo());
- }
+ validationLog("Checking " + url.toString() + " on " +
+ mNetworkAgentInfo.networkInfo.getExtraInfo());
urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
urlConnection.setInstanceFollowRedirects(fetchPac);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
@@ -650,10 +679,8 @@
long responseTimestamp = SystemClock.elapsedRealtime();
httpResponseCode = urlConnection.getResponseCode();
- if (DBG) {
- log("isCaptivePortal: ret=" + httpResponseCode +
- " headers=" + urlConnection.getHeaderFields());
- }
+ validationLog("isCaptivePortal: ret=" + httpResponseCode +
+ " headers=" + urlConnection.getHeaderFields());
// NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
// portal. The only example of this seen so far was a captive portal. For
// the time being go with prior behavior of assuming it's not a captive
@@ -666,12 +693,12 @@
// sign-in to an empty page. Probably the result of a broken transparent proxy.
// See http://b/9972012.
if (httpResponseCode == 200 && urlConnection.getContentLength() == 0) {
- if (DBG) log("Empty 200 response interpreted as 204 response.");
+ validationLog("Empty 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
if (httpResponseCode == 200 && fetchPac) {
- if (DBG) log("PAC fetch 200 response interpreted as 204 response.");
+ validationLog("PAC fetch 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
@@ -679,7 +706,7 @@
httpResponseCode != 204 /* isCaptivePortal */,
requestTimestamp, responseTimestamp);
} catch (IOException e) {
- if (DBG) log("Probably not a portal: exception " + e);
+ validationLog("Probably not a portal: exception " + e);
if (httpResponseCode == 599) {
// TODO: Ping gateway and DNS server and log results.
}
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/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index ea461e5..2c57833 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -23,12 +23,14 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
+import android.content.Intent;
import android.content.ISyncStatusObserver;
import android.content.PeriodicSync;
import android.content.SyncAdapterType;
import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
import android.database.IContentObserver;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
@@ -161,8 +163,9 @@
* Register a content observer tied to a specific user's view of the provider.
* @param userHandle the user whose view of the provider is to be observed. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly handled; all other pseudousers are forbidden.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
+ * are forbidden.
*/
@Override
public void registerContentObserver(Uri uri, boolean notifyForDescendants,
@@ -171,8 +174,17 @@
throw new IllegalArgumentException("You must pass a valid uri and observer");
}
- enforceCrossUserPermission(userHandle,
- "no permission to observe other users' provider view");
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ final int callingUserHandle = UserHandle.getCallingUserId();
+ // Registering an observer for any user other than the calling user requires uri grant or
+ // cross user permission
+ if (callingUserHandle != userHandle &&
+ mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle,
+ "no permission to observe other users' provider view");
+ }
if (userHandle < 0) {
if (userHandle == UserHandle.USER_CURRENT) {
@@ -185,7 +197,7 @@
synchronized (mRootNode) {
mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
- Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
+ uid, pid, userHandle);
if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
" with notifyForDescendants " + notifyForDescendants);
}
@@ -211,8 +223,9 @@
* Notify observers of a particular user's view of the provider.
* @param userHandle the user whose view of the provider is to be notified. May be
* the calling user without requiring any permission, otherwise the caller needs to
- * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and
- * USER_CURRENT are properly interpreted; no other pseudousers are allowed.
+ * hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
+ * Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
+ * allowed.
*/
@Override
public void notifyChange(Uri uri, IContentObserver observer,
@@ -223,11 +236,14 @@
+ " from observer " + observer + ", syncToNetwork " + syncToNetwork);
}
- // Notify for any user other than the caller's own requires permission.
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final int callingUserHandle = UserHandle.getCallingUserId();
- if (userHandle != callingUserHandle) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
- "no permission to notify other users");
+ // Notify for any user other than the caller requires uri grant or cross user permission
+ if (callingUserHandle != userHandle &&
+ mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
+ != PackageManager.PERMISSION_GRANTED) {
+ enforceCrossUserPermission(userHandle, "no permission to notify other users");
}
// We passed the permission check; resolve pseudouser targets as appropriate
@@ -240,7 +256,6 @@
}
}
- final int uid = Binder.getCallingUid();
// This makes it so that future permission checks will be in the context of this
// process rather than the caller's process. We will restore this before returning.
long identityToken = clearCallingIdentity();
@@ -506,6 +521,21 @@
}
@Override
+ public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
+ enforceCrossUserPermission(userId,
+ "no permission to read sync settings for user " + userId);
+ // This makes it so that future permission checks will be in the context of this
+ // process rather than the caller's process. We will restore this before returning.
+ final long identityToken = clearCallingIdentity();
+ try {
+ SyncManager syncManager = getSyncManager();
+ return syncManager.getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ @Override
public boolean getSyncAutomatically(Account account, String providerName) {
return getSyncAutomaticallyAsUser(account, providerName, UserHandle.getCallingUserId());
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 2eb8797..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);
@@ -908,6 +922,10 @@
return types;
}
+ public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
+ return mSyncAdapters.getSyncAdapterPackagesForAuthority(authority, userId);
+ }
+
private void sendSyncAlarmMessage() {
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_ALARM");
mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_SYNC_ALARM);
@@ -953,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;
}
@@ -1232,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.
@@ -1273,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
@@ -2044,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;
@@ -2163,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)) {
@@ -2250,7 +2294,6 @@
// since a sync just finished check if it is time to start a new sync
nextPendingSyncTime = maybeStartNextSyncH();
}
-
break;
}
@@ -2274,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();
@@ -2695,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.
@@ -2845,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);
@@ -2898,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) {
@@ -2916,8 +3018,7 @@
false /* no config settings */)) {
continue;
}
- runSyncFinishedOrCanceledH(null /* no result since this is a cancel */,
- activeSyncContext);
+ runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
}
}
}
@@ -3030,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/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index cff4814..8105675 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -16,6 +16,8 @@
package com.android.server.dreams;
+import com.android.internal.logging.MetricsLogger;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -25,6 +27,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.IBinder.DeathRecipient;
+import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.service.dreams.DreamService;
@@ -55,6 +58,7 @@
private final Handler mHandler;
private final Listener mListener;
private final IWindowManager mIWindowManager;
+ private long mDreamStartTime;
private final Intent mDreamingStartedIntent = new Intent(Intent.ACTION_DREAMING_STARTED)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -123,6 +127,10 @@
mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId);
+ mDreamStartTime = SystemClock.elapsedRealtime();
+ MetricsLogger.visible(mContext,
+ mCurrentDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+
try {
mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
} catch (RemoteException ex) {
@@ -185,6 +193,11 @@
Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
+ ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze
+ ", userId=" + oldDream.mUserId);
+ MetricsLogger.hidden(mContext,
+ oldDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+ MetricsLogger.histogram(mContext,
+ oldDream.mCanDoze ? "dozing_minutes" : "dreaming_minutes" ,
+ (int) ((SystemClock.elapsedRealtime() - mDreamStartTime) / (1000L * 60L)));
mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);
mHandler.removeCallbacks(mStopStubbornDreamRunnable);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c52a1c1..9ee3bc2 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -30,9 +30,11 @@
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.MessageQueue;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
@@ -70,6 +72,7 @@
private static final int MSG_USER_SWITCHING = 10;
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
+ private boolean mIsKeyguard; // true if the authentication client is keyguard
private ClientMonitor mAuthClient = null;
private ClientMonitor mEnrollClient = null;
private ClientMonitor mRemoveClient = null;
@@ -78,6 +81,7 @@
private static final long MS_PER_SEC = 1000;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
+ private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
@@ -97,6 +101,7 @@
private long mHalDeviceId;
private int mFailedAttempts;
private IFingerprintDaemon mDaemon;
+ private PowerManager mPowerManager;
private final Runnable mLockoutReset = new Runnable() {
@Override
@@ -109,6 +114,7 @@
super(context);
mContext = context;
mAppOps = context.getSystemService(AppOpsManager.class);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
@Override
@@ -191,7 +197,11 @@
removeClient(mAuthClient);
}
}
+ }
+ private void userActivity() {
+ long now = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
}
void handleUserSwitching(int userId) {
@@ -498,9 +508,10 @@
*/
private boolean sendAuthenticated(int fpId, int groupId) {
boolean result = false;
+ boolean authenticated = fpId != 0;
if (receiver != null) {
try {
- if (fpId == 0) {
+ if (!authenticated) {
receiver.onAuthenticationFailed(mHalDeviceId);
} else {
Fingerprint fp = !restricted ?
@@ -522,6 +533,11 @@
result |= true; // we have a valid fingerprint
mLockoutReset.run();
}
+ // For fingerprint devices that support touch-to-wake, this will ensure the device
+ // wakes up and turns the screen on when fingerprint is authenticated.
+ if (mIsKeyguard && authenticated) {
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ }
return result;
}
@@ -537,6 +553,12 @@
Slog.w(TAG, "Failed to invoke sendAcquired:", e);
return true; // client failed
}
+ finally {
+ // Good scans will keep the device awake
+ if (acquiredInfo == FINGERPRINT_ACQUIRED_GOOD) {
+ userActivity();
+ }
+ }
}
/*
@@ -589,6 +611,8 @@
};
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+ private static final String KEYGUARD_PACKAGE = "com.android.systemui";
+
@Override // Binder call
public long preEnroll(IBinder token) {
checkPermission(MANAGE_FINGERPRINT);
@@ -638,7 +662,8 @@
@Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
- final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
+ final IFingerprintServiceReceiver receiver, final int flags,
+ final String opPackageName) {
if (!canUseFingerprint(opPackageName)) {
return;
@@ -647,6 +672,7 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ mIsKeyguard = KEYGUARD_PACKAGE.equals(opPackageName);
startAuthentication(token, opId, groupId, receiver, flags, restricted);
}
});
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/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 3850306..45a4829 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -281,8 +281,16 @@
// current setting 24 hours
private static final long NTP_INTERVAL = 24*60*60*1000;
// how long to wait if we have a network error in NTP or XTRA downloading
+ // the initial value of the exponential backoff
// current setting - 5 minutes
private static final long RETRY_INTERVAL = 5*60*1000;
+ // how long to wait if we have a network error in NTP or XTRA downloading
+ // the max value of the exponential backoff
+ // current setting - 4 hours
+ private static final long MAX_RETRY_INTERVAL = 4*60*60*1000;
+
+ private BackOff mNtpBackOff = new BackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL);
+ private BackOff mXtraBackOff = new BackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL);
// true if we are enabled, protected by this
private boolean mEnabled;
@@ -832,9 +840,10 @@
native_inject_time(time, timeReference, (int) certainty);
delay = NTP_INTERVAL;
+ mNtpBackOff.reset();
} else {
if (DEBUG) Log.d(TAG, "requestTime failed");
- delay = RETRY_INTERVAL;
+ delay = mNtpBackOff.nextBackoffMillis();
}
sendMessage(INJECT_NTP_TIME_FINISHED, 0, null);
@@ -875,6 +884,7 @@
Log.d(TAG, "calling native_inject_xtra_data");
}
native_inject_xtra_data(data, data.length);
+ mXtraBackOff.reset();
}
sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
@@ -882,7 +892,8 @@
if (data == null) {
// try again later
// since this is delayed and not urgent we do not hold a wake lock here
- mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA, RETRY_INTERVAL);
+ mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
+ mXtraBackOff.nextBackoffMillis());
}
// release wake lock held by task
@@ -2190,6 +2201,36 @@
pw.append(s);
}
+ /**
+ * A simple implementation of exponential backoff.
+ */
+ private static final class BackOff {
+ private static final int MULTIPLIER = 2;
+ private final long mInitIntervalMillis;
+ private final long mMaxIntervalMillis;
+ private long mCurrentIntervalMillis;
+
+ public BackOff(long initIntervalMillis, long maxIntervalMillis) {
+ mInitIntervalMillis = initIntervalMillis;
+ mMaxIntervalMillis = maxIntervalMillis;
+
+ mCurrentIntervalMillis = mInitIntervalMillis / MULTIPLIER;
+ }
+
+ public long nextBackoffMillis() {
+ if (mCurrentIntervalMillis > mMaxIntervalMillis) {
+ return mMaxIntervalMillis;
+ }
+
+ mCurrentIntervalMillis *= MULTIPLIER;
+ return mCurrentIntervalMillis;
+ }
+
+ public void reset() {
+ mCurrentIntervalMillis = mInitIntervalMillis / MULTIPLIER;
+ }
+ }
+
// for GPS SV statistics
private static final int MAX_SVS = 32;
private static final int EPHEMERIS_MASK = 0;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b0550d6..d4b7256 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);
}
/**
@@ -2090,8 +2093,10 @@
for (UserInfo user : users) {
for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
+ boolean isAllow = mPowerSaveTempWhitelistAppIds.valueAt(i);
int uid = UserHandle.getUid(user.id, appId);
updateRulesForUidLocked(uid);
+ setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, !isAllow);
}
}
}
@@ -2187,11 +2192,6 @@
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.
- setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false);
- }
}
// dispatch changed rule to existing listeners
@@ -2207,15 +2207,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 +2391,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 9c288be..d6a7bf93 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -50,6 +50,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioAttributes;
@@ -72,6 +73,7 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.service.notification.Condition;
@@ -97,6 +99,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;
@@ -440,6 +443,12 @@
return true;
}
+ /** Use this to check if a package can post a notification or toast. */
+ private boolean checkNotificationOp(String pkg, int uid) {
+ return mAppOps.checkOp(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
+ == AppOpsManager.MODE_ALLOWED;
+ }
+
private static final class ToastRecord
{
final int pid;
@@ -622,22 +631,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();
}
}
}
@@ -1906,6 +1917,26 @@
r.dump(pw, " ", getContext());
}
}
+
+ try {
+ pw.println("\n Banned Packages:");
+ for(UserInfo user : UserManager.get(getContext()).getUsers()) {
+ final int userId = user.getUserHandle().getIdentifier();
+ pw.println(" UserId " + userId);
+ final PackageManager packageManager = getContext().getPackageManager();
+ List<PackageInfo> packages = packageManager.getInstalledPackages(0, userId);
+ final int packageCount = packages.size();
+ for (int p = 0; p < packageCount; p++) {
+ final String packageName = packages.get(p).packageName;
+ final int uid = packageManager.getPackageUid(packageName, userId);
+ if (!checkNotificationOp(packageName, uid)) {
+ pw.println(" " + packageName);
+ }
+ }
+ }
+ } catch (NameNotFoundException e) {
+ // pass
+ }
}
}
@@ -1969,6 +2000,9 @@
for (int i=0; i<N; i++) {
final NotificationRecord r = mNotificationList.get(i);
if (r.sbn.getPackageName().equals(pkg) && r.sbn.getUserId() == userId) {
+ if (r.sbn.getId() == id && TextUtils.equals(r.sbn.getTag(), tag)) {
+ break; // Allow updating existing notification
+ }
count++;
if (count >= MAX_PACKAGE_NOTIFICATIONS) {
Slog.e(TAG, "Package has already posted " + count
@@ -2999,19 +3033,8 @@
final int len = list.size();
for (int i=0; i<len; i++) {
NotificationRecord r = list.get(i);
- if (!notificationMatchesUserId(r, userId) || r.sbn.getId() != id) {
- continue;
- }
- if (tag == null) {
- if (r.sbn.getTag() != null) {
- continue;
- }
- } else {
- if (!tag.equals(r.sbn.getTag())) {
- continue;
- }
- }
- if (r.sbn.getPackageName().equals(pkg)) {
+ if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id &&
+ TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) {
return i;
}
}
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
new file mode 100644
index 0000000..8a2abe1
--- /dev/null
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -0,0 +1,698 @@
+/*
+ * 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.server.pm;
+
+import android.Manifest;
+import android.app.DownloadManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal.PackagesProvider;
+import android.content.pm.PackageParser;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.UserHandle;
+import android.provider.CalendarContract;
+import android.provider.ContactsContract;
+import android.provider.MediaStore;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static android.os.Process.FIRST_APPLICATION_UID;
+
+/**
+ * This class is the policy for granting runtime permissions to
+ * platform components and default handlers in the system such
+ * that the device is usable out-of-the-box. For example, the
+ * shell UID is a part of the system and the Phone app should
+ * have phone related permission by default.
+ */
+final class 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";
+
+ private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
+ static {
+ PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
+ PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
+ PHONE_PERMISSIONS.add(Manifest.permission.READ_CALL_LOG);
+ PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG);
+ PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL);
+ PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP);
+ PHONE_PERMISSIONS.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
+ }
+
+ private static final Set<String> CONTACTS_PERMISSIONS = new ArraySet<>();
+ static {
+ CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS);
+ CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS);
+ }
+
+ private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>();
+ static {
+ LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION);
+ LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>();
+ static {
+ CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR);
+ CALENDAR_PERMISSIONS.add(Manifest.permission.WRITE_CALENDAR);
+ }
+
+ private static final Set<String> SMS_PERMISSIONS = new ArraySet<>();
+ static {
+ SMS_PERMISSIONS.add(Manifest.permission.SEND_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.READ_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_WAP_PUSH);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_MMS);
+ SMS_PERMISSIONS.add(Manifest.permission.READ_CELL_BROADCASTS);
+ }
+
+ private static final Set<String> MICROPHONE_PERMISSIONS = new ArraySet<>();
+ static {
+ MICROPHONE_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO);
+ }
+
+ private static final Set<String> CAMERA_PERMISSIONS = new ArraySet<>();
+ static {
+ CAMERA_PERMISSIONS.add(Manifest.permission.CAMERA);
+ }
+
+ private static final Set<String> SENSORS_PERMISSIONS = new ArraySet<>();
+ static {
+ SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS);
+ }
+
+ private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
+ static {
+ STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ }
+
+ private static final Set<String> ACCOUNTS_PERMISSIONS = new ArraySet<>();
+ static {
+ //ACCOUNTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
+ }
+
+ private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
+ static {
+ SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS);
+ }
+
+ private static final Set<String> INSTALLER_PERMISSIONS = new ArraySet<>();
+ static {
+ INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.CLEAR_APP_USER_DATA);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.KILL_UID);
+ }
+
+ private static final Set<String> VERIFIER_PERMISSIONS = new ArraySet<>();
+ static {
+ INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
+ }
+
+ private final PackageManagerService mService;
+
+ private PackagesProvider mImePackagesProvider;
+ private PackagesProvider mLocationPackagesProvider;
+ private PackagesProvider mVoiceInteractionPackagesProvider;
+ private PackagesProvider mSmsAppPackagesProvider;
+ private PackagesProvider mDialerAppPackagesProvider;
+
+ public DefaultPermissionGrantPolicy(PackageManagerService service) {
+ mService = service;
+ }
+
+ public void setImePackagesProviderLPr(PackagesProvider provider) {
+ mImePackagesProvider = provider;
+ }
+
+ public void setLocationPackagesProviderLPw(PackagesProvider provider) {
+ mLocationPackagesProvider = provider;
+ }
+
+ public void setVoiceInteractionPackagesProviderLPw(PackagesProvider provider) {
+ mVoiceInteractionPackagesProvider = provider;
+ }
+
+ public void setSmsAppPackagesProviderLPw(PackagesProvider provider) {
+ mSmsAppPackagesProvider = provider;
+ }
+
+ public void setDialerAppPackagesProviderLPw(PackagesProvider provider) {
+ mDialerAppPackagesProvider = provider;
+ }
+
+ public void grantDefaultPermissions(int userId) {
+ grantPermissionsToSysComponentsAndPrivApps(userId);
+ grantDefaultSystemHandlerPermissions(userId);
+ }
+
+ private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
+ Log.i(TAG, "Granting permissions to platform components for user" + userId);
+
+ synchronized (mService.mPackages) {
+ for (PackageParser.Package pkg : mService.mPackages.values()) {
+ if (!isSysComponentOrPersistentPrivApp(pkg)
+ || !doesPackageSupportRuntimePermissions(pkg)) {
+ continue;
+ }
+ final int permissionCount = pkg.requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = pkg.requestedPermissions.get(i);
+ BasePermission bp = mService.mSettings.mPermissions.get(permission);
+ if (bp != null && bp.isRuntime()) {
+ final int flags = mService.getPermissionFlags(permission,
+ pkg.packageName, userId);
+ if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
+ mService.grantRuntimePermission(pkg.packageName, permission, userId);
+ mService.updatePermissionFlags(permission, pkg.packageName,
+ PackageManager.MASK_PERMISSION_FLAGS,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ if (DEBUG) {
+ Log.i(TAG, "Granted " + permission + " to system component "
+ + pkg.packageName);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void grantDefaultSystemHandlerPermissions(int userId) {
+ Log.i(TAG, "Granting permissions to default platform handlers for user:" + userId);
+
+ final PackagesProvider imePackagesProvider;
+ final PackagesProvider locationPackagesProvider;
+ final PackagesProvider voiceInteractionPackagesProvider;
+ final PackagesProvider smsAppPackagesProvider;
+ final PackagesProvider dialerAppPackagesProvider;
+
+ synchronized (mService.mPackages) {
+ imePackagesProvider = mImePackagesProvider;
+ locationPackagesProvider = mLocationPackagesProvider;
+ voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
+ smsAppPackagesProvider = mSmsAppPackagesProvider;
+ dialerAppPackagesProvider = mDialerAppPackagesProvider;
+ }
+
+ String[] imePackageNames = (imePackagesProvider != null)
+ ? imePackagesProvider.getPackages(userId) : null;
+ String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null)
+ ? voiceInteractionPackagesProvider.getPackages(userId) : null;
+ String[] locationPackageNames = (locationPackagesProvider != null)
+ ? locationPackagesProvider.getPackages(userId) : null;
+ String[] smsAppPackageNames = (smsAppPackagesProvider != null)
+ ? smsAppPackagesProvider.getPackages(userId) : null;
+ String[] dialerAppPackageNames = (dialerAppPackagesProvider != null)
+ ? dialerAppPackagesProvider.getPackages(userId) : null;
+
+ synchronized (mService.mPackages) {
+ // Installers
+ Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
+ installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")),
+ PACKAGE_MIME_TYPE);
+ List<PackageParser.Package> installerPackages =
+ getPrivilegedHandlerActivityPackagesLPr(installerIntent, userId);
+ final int installerCount = installerPackages.size();
+ for (int i = 0; i < installerCount; i++) {
+ PackageParser.Package installPackage = installerPackages.get(i);
+ grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(installPackage, STORAGE_PERMISSIONS, true, userId);
+ }
+
+ // Verifiers
+ Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verifierIntent.setType(PACKAGE_MIME_TYPE);
+ List<PackageParser.Package> verifierPackages =
+ getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId);
+ final int verifierCount = verifierPackages.size();
+ for (int i = 0; i < verifierCount; i++) {
+ PackageParser.Package verifierPackage = verifierPackages.get(i);
+ grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // SetupWizard
+ Intent setupIntent = new Intent(Intent.ACTION_MAIN);
+ setupIntent.addCategory(Intent.CATEGORY_HOME);
+ PackageParser.Package setupPackage = getDefaultSystemHandlerActivityPackageLPr(
+ setupIntent, userId);
+ if (setupPackage != null
+ && doesPackageSupportRuntimePermissions(setupPackage)) {
+ grantRuntimePermissionsLPw(setupPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(setupPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId);
+ }
+
+ // Dialer
+ if (dialerAppPackageNames != null) {
+ for (String dialerAppPackageName : dialerAppPackageNames) {
+ PackageParser.Package dialerPackage = getPackageLPr(dialerAppPackageName);
+ if (dialerPackage != null
+ && doesPackageSupportRuntimePermissions(dialerPackage)) {
+ grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Camera
+ Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ PackageParser.Package cameraPackage = getDefaultSystemHandlerActivityPackageLPr(
+ cameraIntent, userId);
+ if (cameraPackage != null
+ && doesPackageSupportRuntimePermissions(cameraPackage)) {
+ grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(cameraPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Media provider
+ PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackageLPr(
+ MediaStore.AUTHORITY, userId);
+ if (mediaStorePackage != null) {
+ grantRuntimePermissionsLPw(mediaStorePackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Downloads provider
+ PackageParser.Package downloadsPackage = getDefaultProviderAuthorityPackageLPr(
+ "downloads", userId);
+ if (downloadsPackage != null) {
+ grantRuntimePermissionsLPw(downloadsPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Downloads UI
+ Intent downloadsUiIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
+ PackageParser.Package downloadsUiPackage = getDefaultSystemHandlerActivityPackageLPr(
+ downloadsUiIntent, userId);
+ if (downloadsUiPackage != null
+ && doesPackageSupportRuntimePermissions(downloadsUiPackage)) {
+ grantRuntimePermissionsLPw(downloadsUiPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // SMS
+ if (smsAppPackageNames != null) {
+ for (String smsPackageName : smsAppPackageNames) {
+ PackageParser.Package smsPackage = getPackageLPr(smsPackageName);
+ if (smsPackage != null
+ && doesPackageSupportRuntimePermissions(smsPackage)) {
+ grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Calendar
+ Intent calendarIntent = new Intent(Intent.ACTION_MAIN);
+ calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR);
+ PackageParser.Package calendarPackage = getDefaultSystemHandlerActivityPackageLPr(
+ calendarIntent, userId);
+ if (calendarPackage != null
+ && doesPackageSupportRuntimePermissions(calendarPackage)) {
+ grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarPackage, ACCOUNTS_PERMISSIONS, userId);
+ }
+
+ // Calendar provider
+ PackageParser.Package calendarProviderPackage = getDefaultProviderAuthorityPackageLPr(
+ CalendarContract.AUTHORITY, userId);
+ if (calendarProviderPackage != null) {
+ grantRuntimePermissionsLPw(calendarProviderPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, ACCOUNTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarProviderPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Contacts
+ Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
+ contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
+ PackageParser.Package contactsPackage = getDefaultSystemHandlerActivityPackageLPr(
+ contactsIntent, userId);
+ if (contactsPackage != null
+ && doesPackageSupportRuntimePermissions(contactsPackage)) {
+ grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId);
+ }
+
+ // Contacts provider
+ PackageParser.Package contactsProviderPackage = getDefaultProviderAuthorityPackageLPr(
+ ContactsContract.AUTHORITY, userId);
+ if (contactsProviderPackage != null) {
+ grantRuntimePermissionsLPw(contactsProviderPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsProviderPackage, ACCOUNTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsProviderPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Device provisioning
+ Intent deviceProvisionIntent = new Intent(
+ DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
+ PackageParser.Package deviceProvisionPackage =
+ getDefaultSystemHandlerActivityPackageLPr(deviceProvisionIntent, userId);
+ if (deviceProvisionPackage != null
+ && doesPackageSupportRuntimePermissions(deviceProvisionPackage)) {
+ grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId);
+ }
+
+ // Maps
+ Intent mapsIntent = new Intent(Intent.ACTION_MAIN);
+ mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS);
+ PackageParser.Package mapsPackage = getDefaultSystemHandlerActivityPackageLPr(
+ mapsIntent, userId);
+ if (mapsPackage != null
+ && doesPackageSupportRuntimePermissions(mapsPackage)) {
+ grantRuntimePermissionsLPw(mapsPackage, LOCATION_PERMISSIONS, userId);
+ }
+
+ // Email
+ Intent emailIntent = new Intent(Intent.ACTION_MAIN);
+ emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL);
+ PackageParser.Package emailPackage = getDefaultSystemHandlerActivityPackageLPr(
+ emailIntent, userId);
+ if (emailPackage != null
+ && doesPackageSupportRuntimePermissions(emailPackage)) {
+ grantRuntimePermissionsLPw(emailPackage, CONTACTS_PERMISSIONS, userId);
+ }
+
+ // Browser
+ PackageParser.Package browserPackage = null;
+ String defaultBrowserPackage = mService.getDefaultBrowserPackageName(userId);
+ if (defaultBrowserPackage != null) {
+ browserPackage = getPackageLPr(defaultBrowserPackage);
+ }
+ if (browserPackage == null) {
+ Intent browserIntent = new Intent(Intent.ACTION_MAIN);
+ browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
+ browserPackage = getDefaultSystemHandlerActivityPackageLPr(
+ browserIntent, userId);
+ }
+ if (browserPackage != null
+ && doesPackageSupportRuntimePermissions(browserPackage)) {
+ grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
+ }
+
+ // IME
+ if (imePackageNames != null) {
+ for (String imePackageName : imePackageNames) {
+ PackageParser.Package imePackage = getSystemPackageLPr(imePackageName);
+ if (imePackage != null
+ && doesPackageSupportRuntimePermissions(imePackage)) {
+ grantRuntimePermissionsLPw(imePackage, CONTACTS_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Voice interaction
+ if (voiceInteractPackageNames != null) {
+ for (String voiceInteractPackageName : voiceInteractPackageNames) {
+ PackageParser.Package voiceInteractPackage = getSystemPackageLPr(
+ voiceInteractPackageName);
+ if (voiceInteractPackage != null
+ && doesPackageSupportRuntimePermissions(voiceInteractPackage)) {
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ LOCATION_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Location
+ if (locationPackageNames != null) {
+ for (String packageName : locationPackageNames) {
+ PackageParser.Package locationPackage = getSystemPackageLPr(packageName);
+ if (locationPackage != null
+ && doesPackageSupportRuntimePermissions(locationPackage)) {
+ grantRuntimePermissionsLPw(locationPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, SENSORS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, STORAGE_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
+ }
+ }
+
+ public void grantDefaultPermissionsToDefaultSmsAppLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package smsPackage = getPackageLPr(packageName);
+ if (smsPackage != null && doesPackageSupportRuntimePermissions(smsPackage)) {
+ grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId);
+ }
+ }
+
+ public void grantDefaultPermissionsToDefaultDialerAppLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default dialer app for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package dialerPackage = getPackageLPr(packageName);
+ if (dialerPackage != null
+ && doesPackageSupportRuntimePermissions(dialerPackage)) {
+ grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+ }
+
+ public void grantDefaultPermissionsToEnabledCarrierAppsLPr(String[] packageNames, int userId) {
+ Log.i(TAG, "Granting permissions to enabled carrier apps for user:" + userId);
+ if (packageNames == null) {
+ return;
+ }
+ for (String packageName : packageNames) {
+ PackageParser.Package carrierPackage = getSystemPackageLPr(packageName);
+ if (carrierPackage != null
+ && doesPackageSupportRuntimePermissions(carrierPackage)) {
+ grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ public void grantDefaultPermissionsToDefaultBrowserLPr(String packageName, int userId) {
+ Log.i(TAG, "Granting permissions to default browser for user:" + userId);
+ if (packageName == null) {
+ return;
+ }
+ PackageParser.Package browserPackage = getSystemPackageLPr(packageName);
+ if (browserPackage != null
+ && doesPackageSupportRuntimePermissions(browserPackage)) {
+ grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
+ }
+ }
+
+ private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentReceivers(
+ intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
+ 0, userId);
+ return getPrivilegedPackages(handlers);
+ }
+
+ private List<PackageParser.Package> getPrivilegedHandlerActivityPackagesLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentActivities(
+ intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
+ 0, userId);
+ return getPrivilegedPackages(handlers);
+ }
+
+ private List<PackageParser.Package> getPrivilegedPackages(List<ResolveInfo> resolveInfos) {
+ List<PackageParser.Package> handlerPackages = new ArrayList<>();
+ final int handlerCount = resolveInfos.size();
+ for (int i = 0; i < handlerCount; i++) {
+ ResolveInfo handler = resolveInfos.get(i);
+ PackageParser.Package handlerPackage = getPrivilegedPackageLPr(
+ handler.activityInfo.packageName);
+ if (handlerPackage != null) {
+ handlerPackages.add(handlerPackage);
+ }
+ }
+ return handlerPackages;
+ }
+
+ private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId);
+ final int handlerCount = handlers.size();
+ for (int i = 0; i < handlerCount; i++) {
+ ResolveInfo handler = handlers.get(i);
+ // TODO: This is a temporary hack to figure out the setup app.
+ PackageParser.Package handlerPackage = getSystemPackageLPr(
+ handler.activityInfo.packageName);
+ if (handlerPackage != null) {
+ return handlerPackage;
+ }
+ }
+ return null;
+ }
+
+ private PackageParser.Package getDefaultProviderAuthorityPackageLPr(
+ String authority, int userId) {
+ ProviderInfo provider = mService.resolveContentProvider(authority, 0, userId);
+ if (provider != null) {
+ return getSystemPackageLPr(provider.packageName);
+ }
+ return null;
+ }
+
+ private PackageParser.Package getPackageLPr(String packageName) {
+ return mService.mPackages.get(packageName);
+ }
+
+ private PackageParser.Package getSystemPackageLPr(String packageName) {
+ PackageParser.Package pkg = getPackageLPr(packageName);
+ if (pkg != null && pkg.isSystemApp()) {
+ return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
+ }
+ return null;
+ }
+
+ private PackageParser.Package getPrivilegedPackageLPr(String packageName) {
+ PackageParser.Package pkg = mService.mPackages.get(packageName);
+ if (pkg != null && pkg.applicationInfo.isPrivilegedApp()) {
+ return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
+ }
+ return null;
+ }
+
+ private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ int userId) {
+ grantRuntimePermissionsLPw(pkg, permissions, false, userId);
+
+ }
+
+ private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ boolean systemFixed, int userId) {
+ List<String> requestedPermissions = pkg.requestedPermissions;
+
+ if (pkg.isUpdatedSystemApp()) {
+ PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ if (sysPs != null) {
+ requestedPermissions = sysPs.pkg.requestedPermissions;
+ }
+ }
+
+ final int permissionCount = requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = requestedPermissions.get(i);
+ if (permissions.contains(permission)) {
+ final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);
+
+ // If any flags are set to the permission, then it is either set in
+ // its current state by the system or device/profile owner or the user.
+ // In all these cases we do not want to clobber the current state.
+ if (flags == 0) {
+ mService.grantRuntimePermission(pkg.packageName, permission, userId);
+ if (DEBUG) {
+ Log.i(TAG, "Granted " + permission + " to default handler "
+ + pkg.packageName);
+ }
+
+ if (systemFixed) {
+ mService.updatePermissionFlags(permission, pkg.packageName,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ }
+ }
+ }
+ }
+ }
+
+ private void grantInstallPermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ int userId) {
+ List<String> requestedPermissions = pkg.requestedPermissions;
+
+ if (pkg.isUpdatedSystemApp()) {
+ PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ if (sysPs != null) {
+ requestedPermissions = sysPs.pkg.requestedPermissions;
+ }
+ }
+
+ final int permissionCount = requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = requestedPermissions.get(i);
+ if (permissions.contains(permission)) {
+ final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);
+
+ // If any flags are set to the permission, then it is either set in
+ // its current state by the system or device/profile owner or the user.
+ // In all these cases we do not want to clobber the current state.
+ if (flags == 0) {
+ mService.grantInstallPermissionLPw(permission, pkg);
+ if (DEBUG) {
+ Log.i(TAG, "Granted install " + permission + " to " + pkg.packageName);
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
+ return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
+ || ((pkg.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
+ && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
+ }
+
+ private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) {
+ return pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index ef7be30..8dc4bd3 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -41,7 +41,7 @@
@Override
public void onStart() {
Slog.i(TAG, "Waiting for installd to be ready.");
- ping();
+ mInstaller.waitForConnection();
}
private static String escapeNull(String arg) {
@@ -310,14 +310,6 @@
return mInstaller.execute(builder.toString());
}
- public boolean ping() {
- if (mInstaller.execute("ping") < 0) {
- return false;
- } else {
- return true;
- }
- }
-
@Deprecated
public int freeCache(long freeStorageSize) {
return freeCache(null, freeStorageSize);
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/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index d787919..4582828 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -271,7 +271,8 @@
Intent launchIntent = new Intent(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setSourceBounds(sourceBounds);
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.setPackage(component.getPackageName());
long ident = Binder.clearCallingIdentity();
@@ -470,4 +471,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 06e27fc..c86e2f1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
@@ -54,8 +55,8 @@
import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageParser.isApkFile;
-import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.O_CREAT;
@@ -111,6 +112,7 @@
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ActivityIntentInfo;
import android.content.pm.PackageParser.PackageLite;
@@ -195,6 +197,7 @@
import com.android.internal.content.PackageHelper;
import com.android.internal.os.IParcelFileDescriptorFactory;
import com.android.internal.os.SomeArgs;
+import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -207,11 +210,12 @@
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
-import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.pm.PermissionsState.PermissionState;
+import com.android.server.pm.Settings.DatabaseVersion;
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 +257,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 {
@@ -281,6 +285,8 @@
private static final boolean DEBUG_DEXOPT = false;
private static final boolean DEBUG_ABI_SELECTION = false;
+ static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = Build.IS_DEBUGGABLE;
+
private static final int RADIO_UID = Process.PHONE_UID;
private static final int LOG_UID = Process.LOG_UID;
private static final int NFC_UID = Process.NFC_UID;
@@ -306,6 +312,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;
@@ -506,7 +513,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>();
@@ -551,6 +558,25 @@
final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
= new SparseArray<IntentFilterVerificationState>();
+ 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);
@@ -624,7 +650,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) {
@@ -634,6 +660,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);
@@ -708,30 +738,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);
@@ -866,7 +893,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
@@ -878,12 +905,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;
@@ -1066,7 +1096,7 @@
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
}
-
+
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
@@ -1104,13 +1134,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) {
@@ -1496,11 +1531,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: {
@@ -1586,6 +1619,11 @@
grantRequestedRuntimePermissionsForUser(pkg, someUserId);
}
}
+
+ // We could have touched GID membership, so flush out packages.list
+ synchronized (mPackages) {
+ mSettings.writePackageListLPr();
+ }
}
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) {
@@ -1805,7 +1843,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>();
@@ -2152,7 +2190,8 @@
// If this is the first boot, and it is a normal boot, then
// we need to initialize the default preferred apps.
if (!mRestoredSettings && !onlyCore) {
- mSettings.readDefaultPreferredAppsLPw(this, 0);
+ mSettings.applyDefaultPreferredAppsLPw(this, UserHandle.USER_OWNER);
+ applyFactoryDefaultBrowserLPw(UserHandle.USER_OWNER);
}
// If this is first boot after an OTA, and a normal boot, then
@@ -2194,6 +2233,9 @@
// are all flushed. Not really needed, but keeps things nice and
// tidy.
Runtime.getRuntime().gc();
+
+ // Expose private service for system components to use.
+ LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
}
@Override
@@ -2333,14 +2375,72 @@
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "End priming domain verifications");
}
+ private void applyFactoryDefaultBrowserLPw(int userId) {
+ // The default browser app's package name is stored in a string resource,
+ // with a product-specific overlay used for vendor customization.
+ String browserPkg = mContext.getResources().getString(
+ com.android.internal.R.string.default_browser);
+ if (browserPkg != null) {
+ // non-empty string => required to be a known package
+ PackageSetting ps = mSettings.mPackages.get(browserPkg);
+ if (ps == null) {
+ Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
+ browserPkg = null;
+ } else {
+ mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
+ }
+ }
+
+ // Nothing valid explicitly set? Make the factory-installed browser the explicit
+ // default. If there's more than one, just leave everything alone.
+ if (browserPkg == null) {
+ calculateDefaultBrowserLPw(userId);
+ }
+ }
+
+ private void calculateDefaultBrowserLPw(int userId) {
+ List<String> allBrowsers = resolveAllBrowserApps(userId);
+ final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
+ mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
+ }
+
+ private List<String> resolveAllBrowserApps(int userId) {
+ // Match all generic http: browser apps
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.setData(Uri.parse("http:"));
+
+ // Resolve that intent and check that the handleAllWebDataURI boolean is set
+ List<ResolveInfo> list = queryIntentActivities(intent, null, 0, userId);
+
+ final int count = list.size();
+ List<String> result = new ArrayList<String>(count);
+ for (int i=0; i<count; i++) {
+ ResolveInfo info = list.get(i);
+ if (info.activityInfo == null
+ || !info.handleAllWebDataURI
+ || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ || result.contains(info.activityInfo.packageName)) {
+ continue;
+ }
+ result.add(info.activityInfo.packageName);
+ }
+
+ return result;
+ }
+
private void checkDefaultBrowser() {
final int myUserId = UserHandle.myUserId();
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);
- setDefaultBrowserPackageName(null, myUserId);
+ if (packageName != null) {
+ PackageInfo info = getPackageInfo(packageName, 0, myUserId);
+ if (info == null) {
+ Slog.w(TAG, "Default browser no longer installed: " + packageName);
+ synchronized (mPackages) {
+ applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
+ }
+ }
}
}
@@ -2466,7 +2566,7 @@
}
return out;
}
-
+
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
String[] out = new String[names.length];
@@ -2524,6 +2624,21 @@
return null;
}
+ @Override
+ public int getMountExternalMode(int uid) {
+ if (Process.isIsolated(uid)) {
+ return Zygote.MOUNT_EXTERNAL_NONE;
+ } else {
+ if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+ return Zygote.MOUNT_EXTERNAL_WRITE;
+ } else if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
+ return Zygote.MOUNT_EXTERNAL_READ;
+ } else {
+ return Zygote.MOUNT_EXTERNAL_DEFAULT;
+ }
+ }
+ }
+
static PermissionInfo generatePermissionInfo(
BasePermission bp, int flags) {
if (bp.perm != null) {
@@ -2536,7 +2651,7 @@
pi.protectionLevel = bp.protectionLevel;
return pi;
}
-
+
@Override
public PermissionInfo getPermissionInfo(String name, int flags) {
// reader
@@ -3016,7 +3131,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;
@@ -3150,7 +3265,7 @@
}
@Override
- public void grantRuntimePermission(String packageName, String name, int userId) {
+ public void grantRuntimePermission(String packageName, String name, final int userId) {
if (!sUserManager.exists(userId)) {
Log.e(TAG, "No such user:" + userId);
return;
@@ -3163,7 +3278,7 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"grantRuntimePermission");
- boolean gidsChanged = false;
+ final int uid;
final SettingBase sb;
synchronized (mPackages) {
@@ -3179,6 +3294,7 @@
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
+ uid = pkg.applicationInfo.uid;
sb = (SettingBase) pkg.mExtras;
if (sb == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
@@ -3199,18 +3315,30 @@
}
case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
- gidsChanged = true;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
+ }
+ });
} break;
}
- mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
+ mOnPermissionChangeListeners.onPermissionsChanged(uid);
// Not critical if that is lost - app has to request again.
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
- if (gidsChanged) {
- killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
+ if (READ_EXTERNAL_STORAGE.equals(name)
+ || WRITE_EXTERNAL_STORAGE.equals(name)) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ storage.remountUid(uid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
}
@@ -3271,6 +3399,27 @@
}
@Override
+ public void resetRuntimePermissions() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+ "revokeRuntimePermission");
+
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "resetRuntimePermissions");
+ }
+
+ synchronized (mPackages) {
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ }
+ }
+
+ @Override
public int getPermissionFlags(String name, String packageName, int userId) {
if (!sUserManager.exists(userId)) {
return 0;
@@ -3318,16 +3467,12 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"updatePermissionFlags");
- // Only the system can change policy 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;
}
- // Only the package manager can change system flags.
- flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
- flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
-
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -3352,18 +3497,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) {
@@ -3404,6 +3594,21 @@
return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
}
+ void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) {
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp == null) {
+ throw new SecurityException("Missing " + permission + " permission");
+ }
+
+ SettingBase sb = (SettingBase) pkg.mExtras;
+ PermissionsState permissionsState = sb.getPermissionsState();
+
+ if (permissionsState.grantInstallPermission(bp) !=
+ PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ scheduleWriteSettingsLocked();
+ }
+ }
+
@Override
public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
mContext.enforceCallingOrSelfPermission(
@@ -4085,9 +4290,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);
@@ -4105,7 +4327,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -4128,11 +4350,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);
}
@@ -4141,15 +4363,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;
}
@@ -4164,6 +4407,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_PROFILE_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 {
@@ -4203,8 +4507,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());
@@ -4219,7 +4523,7 @@
synchronized (mPackages) {
final int count = candidates.size();
- // First, try to use the domain prefered App. Partition the candidates into four lists:
+ // First, try to use the domain preferred app. Partition the candidates into four lists:
// one for the final results, one for the "do not use ever", one for "undefined status"
// and finally one for "Browser App type".
for (int n=0; n<count; n++) {
@@ -4244,12 +4548,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);
@@ -4567,7 +4882,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -4618,7 +4933,7 @@
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
- intent = intent.getSelector();
+ intent = intent.getSelector();
comp = intent.getComponent();
}
}
@@ -6045,7 +6360,7 @@
+ "): packages=" + suid.packages);
}
}
-
+
// Check if we are renaming from an original package name.
PackageSetting origPackage = null;
String realName = null;
@@ -6065,7 +6380,7 @@
// it is not already done.
pkg.setPackageName(renamed);
}
-
+
} else {
for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
if ((origPackage = mSettings.peekPackageLPr(
@@ -6095,7 +6410,7 @@
}
}
}
-
+
if (mTransferedPackages.contains(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName
+ " was transferred to another, but its .apk remains");
@@ -6120,24 +6435,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;
}
@@ -6253,7 +6568,7 @@
}
final String pkgName = pkg.packageName;
-
+
final long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
pkg.applicationInfo.processName = fixProcessName(
@@ -7719,7 +8034,7 @@
}
}
}
-
+
if (pkgInfo != null) {
grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
}
@@ -7748,7 +8063,6 @@
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
- int[] upgradeUserIds = EMPTY_INT_ARRAY;
int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
boolean changedInstallPermission = false;
@@ -7805,32 +8119,11 @@
if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
// For legacy apps dangerous permissions are install time ones.
grant = GRANT_INSTALL_LEGACY;
- } else if (ps.isSystem()) {
- final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds();
- if (origPermissions.hasInstallPermission(bp.name)) {
- // If a system app had an install permission, then the app was
- // upgraded and we grant the permissions as runtime to all users.
- grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- } else if (!Arrays.equals(updatedUserIds, currentUserIds)) {
- // If users changed since the last permissions update for a
- // system app, we grant the permission as runtime to the new users.
- grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- for (int userId : updatedUserIds) {
- upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId);
- }
- } else {
- // Otherwise, we grant the permission as runtime if the app
- // already had it, i.e. we preserve runtime permissions.
- grant = GRANT_RUNTIME;
- }
} else if (origPermissions.hasInstallPermission(bp.name)) {
// For legacy apps that became modern, install becomes runtime.
grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- } else if (replace) {
- // For upgraded modern apps keep runtime permissions unchanged.
+ } else {
+ // For modern apps keep runtime permissions unchanged.
grant = GRANT_RUNTIME;
}
} break;
@@ -7865,7 +8158,7 @@
switch (grant) {
case GRANT_INSTALL: {
// Revoke this as runtime permission to handle the case of
- // a runtime permssion being downgraded to an install one.
+ // a runtime permission being downgraded to an install one.
for (int userId : UserManagerService.getInstance().getUserIds()) {
if (origPermissions.getRuntimePermissionState(
bp.name, userId) != null) {
@@ -7896,26 +8189,20 @@
case GRANT_RUNTIME: {
// Grant previously granted runtime permissions.
for (int userId : UserManagerService.getInstance().getUserIds()) {
+ PermissionState permissionState = origPermissions
+ .getRuntimePermissionState(bp.name, userId);
+ final int flags = permissionState != null
+ ? permissionState.getFlags() : 0;
if (origPermissions.hasRuntimePermission(bp.name, userId)) {
- PermissionState permissionState = origPermissions
- .getRuntimePermissionState(bp.name, userId);
- final int flags = permissionState.getFlags();
if (permissionsState.grantRuntimePermission(bp, userId) ==
PermissionsState.PERMISSION_OPERATION_FAILURE) {
// If we cannot put the permission as it was, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
- } else {
- // System components not only get the permissions but
- // they are also fixed, so nothing can change that.
- final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
- ? flags
- : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
- // Propagate the permission flags.
- permissionsState.updatePermissionFlags(bp, userId,
- newFlags, newFlags);
}
}
+ // Propagate the permission flags.
+ permissionsState.updatePermissionFlags(bp, userId, flags, flags);
}
} break;
@@ -7925,25 +8212,23 @@
.getInstallPermissionState(bp.name);
final int flags = permissionState != null ? permissionState.getFlags() : 0;
- origPermissions.revokeInstallPermission(bp);
- // We will be transferring the permission flags, so clear them.
- origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
- PackageManager.MASK_PERMISSION_FLAGS, 0);
+ if (origPermissions.revokeInstallPermission(bp)
+ != PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ // We will be transferring the permission flags, so clear them.
+ origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ changedInstallPermission = true;
+ }
// If the permission is not to be promoted to runtime we ignore it and
// also its other flags as they are not applicable to install permissions.
if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
- for (int userId : upgradeUserIds) {
+ for (int userId : currentUserIds) {
if (permissionsState.grantRuntimePermission(bp, userId) !=
PermissionsState.PERMISSION_OPERATION_FAILURE) {
- // System components not only get the permissions but
- // they are also fixed so nothing can change that.
- final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
- ? flags
- : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
// Transfer the permission flags.
permissionsState.updatePermissionFlags(bp, userId,
- newFlags, newFlags);
+ flags, flags);
// If we granted the permission, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
@@ -7995,11 +8280,9 @@
ps.installPermissionsFixed = true;
}
- ps.setPermissionsUpdatedForUserIds(currentUserIds);
-
// Persist the runtime permissions state for users with changes.
for (int userId : changedRuntimePermissionUserIds) {
- mSettings.writeRuntimePermissionsForUserLPr(userId, true);
+ mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
}
@@ -8205,7 +8488,7 @@
PackageParser.ActivityIntentInfo info) {
return packageName.equals(info.activity.owner.packageName);
}
-
+
@Override
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
int match, int userId) {
@@ -8248,6 +8531,7 @@
} else {
res.icon = info.icon;
}
+ res.iconResourceId = info.icon;
res.system = res.activityInfo.applicationInfo.isSystemApp();
return res;
}
@@ -8427,7 +8711,7 @@
PackageParser.ServiceIntentInfo info) {
return packageName.equals(info.service.owner.packageName);
}
-
+
@Override
protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
int match, int userId) {
@@ -8950,6 +9234,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) {
@@ -9372,6 +9657,9 @@
@Override
public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+
boolean result = false;
synchronized (mPackages) {
result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
@@ -9413,12 +9701,17 @@
@Override
public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+
synchronized (mPackages) {
- boolean result = mSettings.setDefaultBrowserPackageNameLPr(packageName, userId);
+ boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
if (packageName != null) {
result |= updateIntentVerificationStatus(packageName,
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
UserHandle.myUserId());
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
+ packageName, userId);
}
return result;
}
@@ -11154,7 +11447,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;
}
@@ -11538,6 +11831,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;
@@ -11751,7 +12048,7 @@
return;
}
- startIntentFilterVerifications(args.user.getIdentifier(), pkg);
+ startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
if (replace) {
replacePackageLI(pkg, parseFlags, scanFlags, args.user,
@@ -11768,7 +12065,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!");
@@ -11781,14 +12079,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) {
@@ -11808,13 +12103,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)) {
@@ -11826,11 +12134,12 @@
}
}
}
+
if (needToVerify) {
+ final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
- boolean needsFilterVerification = filter.hasWebDataURI();
- if (needsFilterVerification && needsNetworkVerificationLPr(filter)) {
+ if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Verification needed for IntentFilter:" + filter.toString());
mIntentFilterVerifier.addOneIntentFilterVerification(
@@ -11875,13 +12184,6 @@
}
}
- private boolean isSystemComponentOrPersistentPrivApp(PackageParser.Package pkg) {
- return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
- || ((pkg.applicationInfo.privateFlags
- & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
- && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
- }
-
private static boolean isMultiArch(PackageSetting ps) {
return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
}
@@ -12494,6 +12796,8 @@
if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
scheduleWritePackageRestrictionsLocked(removeUser);
}
+ revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
+ removeUser);
}
return true;
}
@@ -12700,17 +13004,49 @@
| PackageManager.FLAG_PERMISSION_USER_FIXED
| PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+ revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
+ }
+
+ /**
+ * Revokes granted runtime permissions and clears all flags.
+ *
+ * @param permissionsState The permission state to reset.
+ * @param userId The device user for which to do a reset.
+ */
+ private void revokeRuntimePermissionsAndClearAllFlagsLocked(
+ PermissionsState permissionsState, int userId) {
+ revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
+ PackageManager.MASK_PERMISSION_FLAGS);
+ }
+
+ /**
+ * Revokes granted runtime permissions and clears certain flags.
+ *
+ * @param permissionsState The permission state to reset.
+ * @param userId The device user for which to do a reset.
+ * @param flags The flags that is going to be reset.
+ */
+ private void revokeRuntimePermissionsAndClearFlagsLocked(
+ PermissionsState permissionsState, final int userId, int flags) {
boolean needsWrite = false;
for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
BasePermission bp = mSettings.mPermissions.get(state.getName());
if (bp != null) {
permissionsState.revokeRuntimePermission(bp, userId);
- permissionsState.updatePermissionFlags(bp, userId, userSetFlags, 0);
+ permissionsState.updatePermissionFlags(bp, userId, flags, 0);
needsWrite = true;
}
}
+ // Ensure default permissions are never cleared.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ });
+
if (needsWrite) {
mSettings.writeRuntimePermissionsForUserLPr(userId, true);
}
@@ -13136,15 +13472,15 @@
@Override
public void resetPreferredActivities(int userId) {
- /* TODO: Actually use userId. Why is it being passed in? */
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
// writer
synchronized (mPackages) {
- int user = UserHandle.getCallingUserId();
- clearPackagePreferredActivitiesLPw(null, user);
- mSettings.readDefaultPreferredAppsLPw(this, user);
- scheduleWritePackageRestrictionsLocked(user);
+ clearPackagePreferredActivitiesLPw(null, userId);
+ mSettings.applyDefaultPreferredAppsLPw(this, userId);
+ applyFactoryDefaultBrowserLPw(userId);
+
+ scheduleWritePackageRestrictionsLocked(userId);
}
}
@@ -13244,9 +13580,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) {
@@ -13287,32 +13659,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());
@@ -13642,6 +14116,8 @@
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
+ int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+
synchronized (mPackages) {
// Verify that all of the preferred activity components actually
// exist. It is possible for applications to be updated and at
@@ -13671,9 +14147,21 @@
mSettings.mPreferredActivities.keyAt(i));
}
}
+
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
+ grantPermissionsUserIds = ArrayUtils.appendInt(
+ grantPermissionsUserIds, userId);
+ }
+ }
}
sUserManager.systemReady();
+ // If we upgraded grant all default permissions before kicking off.
+ for (int userId : grantPermissionsUserIds) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+
// Kick off any messages waiting for system ready
if (mPostSystemReadyMessages != null) {
for (Message msg : mPostSystemReadyMessages) {
@@ -13801,7 +14289,8 @@
boolean checkin = false;
String packageName = null;
-
+ ArraySet<String> permissionNames = null;
+
int opti = 0;
while (opti < args.length) {
String opt = args[opti];
@@ -13824,6 +14313,7 @@
pw.println(" k[eysets]: print known keysets");
pw.println(" r[esolvers]: dump intent resolvers");
pw.println(" perm[issions]: dump permissions");
+ pw.println(" permission [name ...]: dump declaration and use of given permission");
pw.println(" pref[erred]: print preferred package settings");
pw.println(" preferred-xml [--full]: print preferred package settings as xml");
pw.println(" prov[iders]: dump content providers");
@@ -13865,6 +14355,18 @@
dumpState.setDump(DumpState.DUMP_RESOLVERS);
} else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PERMISSIONS);
+ } else if ("permission".equals(cmd)) {
+ if (opti >= args.length) {
+ pw.println("Error: permission requires permission name");
+ return;
+ }
+ permissionNames = new ArraySet<>();
+ while (opti < args.length) {
+ permissionNames.add(args[opti]);
+ opti++;
+ }
+ dumpState.setDump(DumpState.DUMP_PERMISSIONS
+ | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
} else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PREFERRED);
} else if ("preferred-xml".equals(cmd)) {
@@ -14085,7 +14587,9 @@
}
}
- if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
+ if (!checkin
+ && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
+ && packageName == null) {
pw.println();
int count = mSettings.mPackages.size();
if (count == 0) {
@@ -14145,8 +14649,8 @@
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
- mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
- if (packageName == null) {
+ mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
+ if (packageName == null && permissionNames == null) {
for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
if (iperm == 0) {
if (dumpState.onTitlePrinted())
@@ -14206,11 +14710,11 @@
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
- mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
- mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
@@ -14651,7 +15155,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());
@@ -15058,12 +15562,20 @@
if (mInstaller != null) {
mInstaller.createUserConfig(userHandle);
mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
+ applyFactoryDefaultBrowserLPw(userHandle);
}
}
- void newUserCreatedLILPw(int userHandle) {
- // Adding a user requires updating runtime permissions for system apps.
- updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ void newUserCreatedLILPw(final int userHandle) {
+ // 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(userHandle);
+ }
+ });
}
@Override
@@ -15415,4 +15927,74 @@
}
}
}
+
+ private class PackageManagerInternalImpl extends PackageManagerInternal {
+ @Override
+ public void setLocationPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setImePackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
+ }
+ }
+
+ @Override
+ public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setSmsAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setDialerAppPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
+ packageName, userId);
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
+ packageName, userId);
+ }
+ }
+ }
+
+ @Override
+ public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+ enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
+ packageNames, userId);
+ }
+ }
+
+ 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/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index f62c00c..6f46f69 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -24,7 +24,6 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageUserState;
import android.os.storage.VolumeInfo;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.SparseArray;
@@ -223,7 +222,6 @@
* Make a shallow copy of this package settings.
*/
public void copyFrom(PackageSettingBase base) {
- setPermissionsUpdatedForUserIds(base.getPermissionsUpdatedForUserIds());
mPermissionsState.copyFrom(base.mPermissionsState);
primaryCpuAbiString = base.primaryCpuAbiString;
secondaryCpuAbiString = base.secondaryCpuAbiString;
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index ad662be..57ef284 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -219,6 +219,22 @@
}
/**
+ * Returns whether the state has any known request for the given permission name,
+ * whether or not it has been granted.
+ */
+ public boolean hasRequestedPermission(ArraySet<String> names) {
+ if (mPermissions == null) {
+ return false;
+ }
+ for (int i=names.size()-1; i>=0; i--) {
+ if (mPermissions.get(names.valueAt(i)) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Gets all permissions for a given device user id regardless if they
* are install time or runtime permissions.
*
@@ -344,6 +360,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
@@ -430,7 +462,7 @@
}
}
- return permissionStates;
+ return permissionStates;
}
private int grantPermission(BasePermission permission, int userId) {
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index c35258a..5cf92a9 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -18,16 +18,11 @@
import android.content.pm.ApplicationInfo;
-import java.util.Arrays;
-
abstract class SettingBase {
- private static final int[] USERS_NONE = new int[0];
-
int pkgFlags;
int pkgPrivateFlags;
protected final PermissionsState mPermissionsState;
- private int[] mPermissionsUpdatedForUserIds = USERS_NONE;
SettingBase(int pkgFlags, int pkgPrivateFlags) {
setFlags(pkgFlags);
@@ -39,29 +34,12 @@
pkgFlags = base.pkgFlags;
pkgPrivateFlags = base.pkgPrivateFlags;
mPermissionsState = new PermissionsState(base.mPermissionsState);
- setPermissionsUpdatedForUserIds(base.mPermissionsUpdatedForUserIds);
}
public PermissionsState getPermissionsState() {
return mPermissionsState;
}
- public int[] getPermissionsUpdatedForUserIds() {
- return mPermissionsUpdatedForUserIds;
- }
-
- public void setPermissionsUpdatedForUserIds(int[] userIds) {
- if (Arrays.equals(mPermissionsUpdatedForUserIds, userIds)) {
- return;
- }
-
- if (userIds == USERS_NONE) {
- mPermissionsUpdatedForUserIds = userIds;
- } else {
- mPermissionsUpdatedForUserIds = Arrays.copyOf(userIds, userIds.length);
- }
- }
-
void setFlags(int pkgFlags) {
this.pkgFlags = pkgFlags
& (ApplicationInfo.FLAG_SYSTEM
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cd50946..0ad2b4a 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";
@@ -193,6 +195,7 @@
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
private static final String ATTR_PACKAGE_NAME= "packageName";
+ private static final String ATTR_FINGERPRINT = "fingerprint";
private final Object mLock;
@@ -206,10 +209,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 +761,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 +785,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);
+ }
}
/*
@@ -1056,7 +1073,9 @@
ArraySet<String> currentDomains = current.getIntentFilterVerificationInfo().getDomains();
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
for (PackageSetting ps : mPackages.values()) {
- if (ps == null || ps.pkg.packageName.equals(packageName)) continue;
+ if (ps == null || ps.pkg == null || packageName.equals(ps.pkg.packageName)) {
+ continue;
+ }
IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
if (ivi == null) {
continue;
@@ -1112,7 +1131,7 @@
return result;
}
- boolean setDefaultBrowserPackageNameLPr(String packageName, int userId) {
+ boolean setDefaultBrowserPackageNameLPw(String packageName, int userId) {
if (userId == UserHandle.USER_ALL) {
return false;
}
@@ -1139,17 +1158,6 @@
return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
}
- boolean isFirstRuntimePermissionsBoot() {
- return !getUserRuntimePermissionsFile(UserHandle.USER_OWNER).exists();
- }
-
- void deleteRuntimePermissionsFiles() {
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- File file = getUserRuntimePermissionsFile(userId);
- file.delete();
- }
- }
-
private File getUserPackagesStateBackupFile(int userId) {
return new File(Environment.getUserSystemDirectory(userId),
"package-restrictions-backup.xml");
@@ -1170,6 +1178,16 @@
}
}
+ boolean areDefaultRuntimePermissionsGrantedLPr(int userId) {
+ return mRuntimePermissionsPersistence
+ .areDefaultRuntimPermissionsGrantedLPr(userId);
+ }
+
+ void onDefaultRuntimePermissionsGrantedLPr(int userId) {
+ mRuntimePermissionsPersistence
+ .onDefaultRuntimePermissionsGrantedLPr(userId);
+ }
+
/**
* Returns whether the current database has is older than {@code version}
* for apps on internal storage.
@@ -1270,13 +1288,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);
}
@@ -1290,7 +1308,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;
@@ -1574,6 +1616,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);
@@ -2023,6 +2121,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");
@@ -2098,7 +2213,7 @@
}
final ApplicationInfo ai = pkg.pkg.applicationInfo;
- final String dataPath = ai.dataDir;
+ final String dataPath = new File(ai.dataDir).getCanonicalPath();
final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
final int[] gids = pkg.getPermissionsState().computeGids(userIds);
@@ -2452,6 +2567,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 {
@@ -2466,6 +2583,22 @@
} catch (NumberFormatException e) {
}
mFingerprint = parser.getAttributeValue(null, "fingerprint");
+
+ // If the build is setup to drop runtime permissions
+ // on update drop the files before loading them.
+ if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
+ if (!Build.FINGERPRINT.equals(mFingerprint)) {
+ if (users == null) {
+ mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(
+ UserHandle.USER_OWNER);
+ } else {
+ for (UserInfo user : users) {
+ mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(
+ user.id);
+ }
+ }
+ }
+ }
} else if (tagName.equals("database-version")) {
mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
try {
@@ -2554,15 +2687,21 @@
} else {
if (users == null) {
readPackageRestrictionsLPr(0);
- mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER);
} else {
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id);
- mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
}
}
}
+ if (users == null) {
+ mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER);
+ } else {
+ for (UserInfo user : users) {
+ mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
+ }
+ }
+
/*
* Make sure all the updated system packages have their shared users
* associated with them.
@@ -2582,7 +2721,7 @@
return true;
}
- void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
+ void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
// First pull data from any pre-installed apps.
for (PackageSetting ps : mPackages.values()) {
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
@@ -3056,18 +3195,6 @@
}
}
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- ps.setPermissionsUpdatedForUserIds(userIds);
- }
-
mDisabledSysPackages.put(name, ps);
}
@@ -3364,18 +3491,6 @@
XmlUtils.skipCurrentTag(parser);
}
}
-
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- packageSetting.setPermissionsUpdatedForUserIds(userIds);
- }
} else {
XmlUtils.skipCurrentTag(parser);
}
@@ -3493,18 +3608,6 @@
XmlUtils.skipCurrentTag(parser);
}
}
-
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- su.setPermissionsUpdatedForUserIds(userIds);
- }
} else {
XmlUtils.skipCurrentTag(parser);
}
@@ -3526,7 +3629,7 @@
UserHandle.getUid(userHandle, ps.appId), userHandle,
ps.pkg.applicationInfo.seinfo);
}
- readDefaultPreferredAppsLPw(service, userHandle);
+ applyDefaultPreferredAppsLPw(service, userHandle);
writePackageRestrictionsLPr(userHandle);
writePackageListLPr(userHandle);
}
@@ -3789,8 +3892,9 @@
ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
};
- void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
- SimpleDateFormat sdf, Date date, List<UserInfo> users) {
+ void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
+ ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
+ Date date, List<UserInfo> users) {
if (checkinTag != null) {
pw.print(checkinTag);
pw.print(",");
@@ -3861,10 +3965,13 @@
}
pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg);
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
- pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
- pw.print(prefix); pw.print(" legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
- pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
- pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ if (permissionNames == null) {
+ pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
+ pw.print(prefix); pw.print(" legacyNativeLibraryDir=");
+ pw.println(ps.legacyNativeLibraryPathString);
+ pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
+ pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ }
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
@@ -3877,8 +3984,10 @@
pw.println(ps.pkg.applicationInfo.toString());
pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
FLAG_DUMP_SPEC); pw.println();
- pw.print(prefix); pw.print(" priavateFlags="); printFlags(pw,
- ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ if (ps.pkg.applicationInfo.privateFlags != 0) {
+ pw.print(prefix); pw.print(" privateFlags="); printFlags(pw,
+ ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ }
pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
pw.print(prefix); pw.print(" supportsScreens=[");
boolean first = true;
@@ -3971,9 +4080,9 @@
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
pw.println();
- if (ps.sharedUser == null) {
+ if (ps.sharedUser == null || permissionNames != null) {
PermissionsState permissionsState = ps.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix + " ", permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
}
for (UserInfo user : users) {
@@ -3997,28 +4106,31 @@
if (ps.sharedUser == null) {
PermissionsState permissionsState = ps.getPermissionsState();
dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id));
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissionsState
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState
.getRuntimePermissionStates(user.id));
}
- ArraySet<String> cmp = ps.getDisabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" disabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ if (permissionNames == null) {
+ ArraySet<String> cmp = ps.getDisabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" disabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
- }
- cmp = ps.getEnabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" enabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ cmp = ps.getEnabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" enabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
}
}
}
- void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
+ void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date date = new Date();
boolean printedSomething = false;
@@ -4028,6 +4140,10 @@
&& !packageName.equals(ps.name)) {
continue;
}
+ if (permissionNames != null
+ && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin && packageName != null) {
dumpState.setSharedUser(ps.sharedUser);
@@ -4039,11 +4155,11 @@
pw.println("Packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "pkg" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users);
}
printedSomething = false;
- if (!checkin && mRenamedPackages.size() > 0) {
+ if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) {
@@ -4067,7 +4183,7 @@
}
printedSomething = false;
- if (mDisabledSysPackages.size() > 0) {
+ if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
for (final PackageSetting ps : mDisabledSysPackages.values()) {
if (packageName != null && !packageName.equals(ps.realName)
&& !packageName.equals(ps.name)) {
@@ -4079,17 +4195,22 @@
pw.println("Hidden system packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "dis" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
+ users);
}
}
}
- void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState) {
boolean printedSomething = false;
for (BasePermission p : mPermissions.values()) {
if (packageName != null && !packageName.equals(p.sourcePackage)) {
continue;
}
+ if (permissionNames != null && !permissionNames.contains(p.name)) {
+ continue;
+ }
if (!printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
@@ -4119,13 +4240,17 @@
}
}
- void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState,
- boolean checkin) {
+ void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
boolean printedSomething = false;
for (SharedUserSetting su : mSharedUsers.values()) {
if (packageName != null && su != dumpState.getSharedUser()) {
continue;
}
+ if (permissionNames != null
+ && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin) {
if (!printedSomething) {
if (dumpState.onTitlePrinted())
@@ -4143,7 +4268,7 @@
pw.print(prefix); pw.print("userId="); pw.println(su.userId);
PermissionsState permissionsState = su.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix, permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
for (int userId : UserManagerService.getInstance().getUserIds()) {
final int[] gids = permissionsState.computeGids(userId);
@@ -4152,7 +4277,7 @@
if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
dumpGidsLPr(pw, prefix + " ", gids);
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissions);
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions);
}
}
} else {
@@ -4197,11 +4322,15 @@
}
}
- void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix,
+ void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
List<PermissionState> permissionStates) {
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("runtime permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(
@@ -4210,12 +4339,16 @@
}
}
- void dumpInstallPermissionsLPr(PrintWriter pw, String prefix,
+ void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
PermissionsState permissionsState) {
List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("install permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(
@@ -4242,15 +4375,33 @@
private final Object mLock;
@GuardedBy("mLock")
- private SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
+ private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
@GuardedBy("mLock")
- private SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
+ // The mapping keys are user ids.
+ private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
+
+ @GuardedBy("mLock")
+ // The mapping keys are user ids.
+ private final SparseArray<String> mFingerprints = new SparseArray<>();
+
+ @GuardedBy("mLock")
+ // The mapping keys are user ids.
+ private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
public RuntimePermissionPersistence(Object lock) {
mLock = lock;
}
+ public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
+ return mDefaultPermissionsGranted.get(userId);
+ }
+
+ public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
+ mFingerprints.put(userId, Build.FINGERPRINT);
+ writePermissionsForUserAsyncLPr(userId);
+ }
+
public void writePermissionsForUserSyncLPr(int userId) {
mHandler.removeMessages(userId);
writePermissionsSync(userId);
@@ -4335,6 +4486,11 @@
serializer.startDocument(null, true);
serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
+ String fingerprint = mFingerprints.get(userId);
+ if (fingerprint != null) {
+ serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
+ }
+
final int packageCount = permissionsForPackage.size();
for (int i = 0; i < packageCount; i++) {
String packageName = permissionsForPackage.keyAt(i);
@@ -4359,13 +4515,14 @@
serializer.endDocument();
destination.finishWrite(out);
- // Any error while writing is fatal.
+ if (Build.FINGERPRINT.equals(fingerprint)) {
+ mDefaultPermissionsGranted.put(userId, true);
+ }
+ // Any error while writing is fatal.
} catch (Throwable t) {
Slog.wtf(PackageManagerService.TAG,
"Failed to write settings, restoring backup", t);
destination.failWrite(out);
- throw new IllegalStateException("Failed to write runtime permissions,"
- + " restoring backup", t);
} finally {
IoUtils.closeQuietly(out);
}
@@ -4397,6 +4554,10 @@
}
}
+ public void deleteUserRuntimePermissionsFile(int userId) {
+ getUserRuntimePermissionsFile(userId).delete();
+ }
+
public void readStateForUserSyncLPr(int userId) {
File permissionsFile = getUserRuntimePermissionsFile(userId);
if (!permissionsFile.exists()) {
@@ -4435,6 +4596,13 @@
}
switch (parser.getName()) {
+ case TAG_RUNTIME_PERMISSIONS: {
+ String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
+ mFingerprints.put(userId, fingerprint);
+ final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
+ mDefaultPermissionsGranted.put(userId, defaultsGranted);
+ } break;
+
case TAG_PACKAGE: {
String name = parser.getAttributeValue(null, ATTR_NAME);
PackageSetting ps = mPackages.get(name);
@@ -4489,22 +4657,12 @@
? Integer.parseInt(flagsStr, 16) : 0;
if (granted) {
- if (permissionsState.grantRuntimePermission(bp, userId) ==
- PermissionsState.PERMISSION_OPERATION_FAILURE) {
- Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name);
- } else {
- permissionsState.updatePermissionFlags(bp, userId,
+ permissionsState.grantRuntimePermission(bp, userId);
+ permissionsState.updatePermissionFlags(bp, userId,
PackageManager.MASK_PERMISSION_FLAGS, flags);
-
- }
} else {
- if (permissionsState.revokeRuntimePermission(bp, userId) ==
- PermissionsState.PERMISSION_OPERATION_FAILURE) {
- Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name);
- } else {
- permissionsState.updatePermissionFlags(bp, userId,
- PackageManager.MASK_PERMISSION_FLAGS, flags);
- }
+ permissionsState.updatePermissionFlags(bp, userId,
+ PackageManager.MASK_PERMISSION_FLAGS, flags);
}
} break;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4082ff3..4300df6 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_PROFILE_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_PROFILE_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 6fb9a5c..764e4d3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,15 +51,18 @@
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -92,6 +95,8 @@
import android.view.KeyCharacterMap.FallbackAction;
import android.view.KeyEvent;
import android.view.MotionEvent;
+
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.policy.PhoneWindow;
import android.view.Surface;
import android.view.View;
@@ -266,6 +271,7 @@
SearchManager mSearchManager;
AccessibilityManager mAccessibilityManager;
BurnInProtectionHelper mBurnInProtectionHelper;
+ AppOpsManager mAppOpsManager;
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -1033,6 +1039,11 @@
case MULTI_PRESS_POWER_NOTHING:
break;
case MULTI_PRESS_POWER_THEATER_MODE:
+ if (!isUserSetupComplete()) {
+ Slog.i(TAG, "Ignoring toggling theater mode - device not setup.");
+ break;
+ }
+
if (isTheaterModeEnabled()) {
Slog.i(TAG, "Toggling theater mode off.");
Settings.Global.putInt(mContext.getContentResolver(),
@@ -1254,6 +1265,7 @@
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+ mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -1688,6 +1700,8 @@
if (mImmersiveModeConfirmation != null) {
mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
}
+ }
+ synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
PolicyControl.reloadFromSetting(mContext);
}
if (updateRotation) {
@@ -1809,6 +1823,25 @@
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
if (permission != null) {
+ if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
+ final int callingUid = Binder.getCallingUid();
+ // check if this is a system uid first before bothering with
+ // obtaining package name
+ if (callingUid == Process.SYSTEM_UID) {
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
+ final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid,
+ attrs.packageName);
+ if (mode == AppOpsManager.MODE_DEFAULT) {
+ if (mContext.checkCallingPermission(permission) !=
+ PackageManager.PERMISSION_GRANTED) {
+ return WindowManagerGlobal.ADD_PERMISSION_DENIED;
+ }
+ }
+ return WindowManagerGlobal.ADD_OKAY;
+ }
+
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
@@ -2734,6 +2767,14 @@
if (!keyguardOn) {
voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
} else {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
}
@@ -3918,7 +3959,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;
@@ -4033,9 +4075,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;
@@ -4044,8 +4086,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;
@@ -5192,6 +5233,14 @@
}
void launchVoiceAssistWithWakeLock(boolean keyguardActive) {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
Intent voiceIntent =
new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive);
@@ -5306,6 +5355,7 @@
public void finishedGoingToSleep(int why) {
EventLog.writeEvent(70000, 0);
if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
+ MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
// We must get this work done here because the power manager will drop
// the wake lock and let the system suspend once this function returns.
@@ -5364,10 +5414,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..5a0bee9 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:
@@ -3116,7 +3117,7 @@
return;
}
- if (eventTime > SystemClock.uptimeMillis()) {
+ if (eventTime > now) {
throw new IllegalArgumentException("event time must not be in the future");
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 58c3ea1..4692403 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -24,4 +24,5 @@
void notificationLightPulse(int argb, int onMillis, int offMillis);
void notificationLightOff();
void showScreenPinningRequest();
+ void showAssistDisclosure();
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 5669f30..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;
@@ -154,6 +155,16 @@
}
}
}
+
+ @Override
+ public void showAssistDisclosure() {
+ if (mBar != null) {
+ try {
+ mBar.showAssistDisclosure();
+ } catch (RemoteException e) {
+ }
+ }
+ }
};
// ================================================================================
@@ -650,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/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 9abdf21..b165b42 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -20,12 +20,21 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageManagerInternal;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.DefaultDialerManager;
import android.util.Slog;
+import com.android.internal.telephony.SmsApplication;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
/**
@@ -48,7 +57,7 @@
connectToTelecom();
}
}, 0);
-
+ SmsApplication.getDefaultMmsApplication(mContext, false);
ServiceManager.addService(Context.TELECOM_SERVICE, service);
} catch (RemoteException e) {
Slog.w(TAG, "Failed linking to death.");
@@ -73,6 +82,7 @@
public TelecomLoaderService(Context context) {
super(context);
mContext = context;
+ registerDefaultAppProviders();
}
@Override
@@ -82,6 +92,7 @@
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
+ registerDefaultAppNotifier();
connectToTelecom();
}
}
@@ -104,4 +115,74 @@
mServiceConnection = serviceConnection;
}
}
+
+ private void registerDefaultAppProviders() {
+ final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+
+ // Set a callback for the package manager to query the default sms app.
+ packageManagerInternal.setSmsAppPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ return new String[]{smsComponent.getPackageName()};
+ }
+ return null;
+ }
+ });
+
+ // Set a callback for the package manager to query the default dialer app.
+ packageManagerInternal.setDialerAppPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext);
+ if (packageName != null) {
+ return new String[]{packageName};
+ }
+ return null;
+ }
+ });
+ }
+
+ private void registerDefaultAppNotifier() {
+ final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+
+ // Notify the package manager on default app changes
+ final Uri defaultSmsAppUri = Settings.Secure.getUriFor(
+ Settings.Secure.SMS_DEFAULT_APPLICATION);
+ final Uri defaultDialerAppUri = Settings.Secure.getUriFor(
+ Settings.Secure.DIALER_DEFAULT_APPLICATION);
+
+ ContentObserver contentObserver = new ContentObserver(
+ new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (defaultSmsAppUri.equals(uri)) {
+ ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
+ mContext, true);
+ if (smsComponent != null) {
+ packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp(
+ smsComponent.getPackageName(), userId);
+ }
+ } else if (defaultDialerAppUri.equals(uri)) {
+ String packageName = DefaultDialerManager.getDefaultDialerApplication(
+ mContext);
+ if (packageName != null) {
+ packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp(
+ packageName, userId);
+ }
+ }
+ }
+ };
+
+ mContext.getContentResolver().registerContentObserver(defaultSmsAppUri,
+ false, contentObserver, UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(defaultDialerAppUri,
+ false, contentObserver, UserHandle.USER_ALL);
+ }
}
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index f9b5b9a..f6b1705 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -111,8 +111,8 @@
public boolean isRatingBlocked(TvContentRating rating) {
loadIfNeeded();
synchronized (mBlockedRatings) {
- for (TvContentRating blcokedRating : mBlockedRatings) {
- if (rating.contains(blcokedRating)) {
+ for (TvContentRating blockedRating : mBlockedRatings) {
+ if (rating.contains(blockedRating)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index de271b8..a035826 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -47,11 +47,10 @@
public static final int EVENT_FIRST_FRAME_CAPTURED = 4;
public interface Callback {
- public void onDeviceAvailable(
- TvInputHardwareInfo info, TvStreamConfig[] configs);
- public void onDeviceUnavailable(int deviceId);
- public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
- public void onFirstFrameCaptured(int deviceId, int streamId);
+ void onDeviceAvailable(TvInputHardwareInfo info, TvStreamConfig[] configs);
+ void onDeviceUnavailable(int deviceId);
+ void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
+ void onFirstFrameCaptured(int deviceId, int streamId);
}
private native long nativeOpen(MessageQueue queue);
@@ -152,7 +151,7 @@
// Handler.Callback implementation
- private final Queue<Message> mPendingMessageQueue = new LinkedList<Message>();
+ private final Queue<Message> mPendingMessageQueue = new LinkedList<>();
@Override
public boolean handleMessage(Message msg) {
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 444969f..7f4c42b 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -252,13 +252,8 @@
Connection connection, int callingUid, int resolvedUserId) {
Integer connectionCallingUid = connection.getCallingUidLocked();
Integer connectionResolvedUserId = connection.getResolvedUserIdLocked();
- if (connectionCallingUid == null || connectionResolvedUserId == null) {
- return true;
- }
- if (connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId) {
- return true;
- }
- return false;
+ return connectionCallingUid == null || connectionResolvedUserId == null
+ || connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId;
}
private int convertConnectedToState(boolean connected) {
@@ -303,7 +298,6 @@
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(connection.getConfigsLocked().length > 0), 0,
info.getId()).sendToTarget();
- return;
}
}
}
@@ -435,7 +429,7 @@
*/
public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int callingUid,
int resolvedUserId) {
- List<TvStreamConfig> configsList = new ArrayList<TvStreamConfig>();
+ List<TvStreamConfig> configsList = new ArrayList<>();
synchronized (mLock) {
int deviceId = findDeviceIdForInputIdLocked(inputId);
if (deviceId < 0) {
@@ -508,25 +502,31 @@
private void handleVolumeChange(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
- int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (streamType != AudioManager.STREAM_MUSIC) {
- return;
+ switch (action) {
+ case AudioManager.VOLUME_CHANGED_ACTION: {
+ int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ if (streamType != AudioManager.STREAM_MUSIC) {
+ return;
+ }
+ int index = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
+ if (index == mCurrentIndex) {
+ return;
+ }
+ mCurrentIndex = index;
+ break;
}
- int index = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
- if (index == mCurrentIndex) {
- return;
+ case AudioManager.STREAM_MUTE_CHANGED_ACTION: {
+ int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ if (streamType != AudioManager.STREAM_MUSIC) {
+ return;
+ }
+ // volume index will be updated at onMediaStreamVolumeChanged() through
+ // updateVolume().
+ break;
}
- mCurrentIndex = index;
- } else if (action.equals(AudioManager.STREAM_MUTE_CHANGED_ACTION)) {
- int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (streamType != AudioManager.STREAM_MUSIC) {
+ default:
+ Slog.w(TAG, "Unrecognized intent: " + intent);
return;
- }
- // volume index will be updated at onMediaStreamVolumeChanged() through updateVolume().
- } else {
- Slog.w(TAG, "Unrecognized intent: " + intent);
- return;
}
synchronized (mLock) {
for (int i = 0; i < mConnections.size(); ++i) {
@@ -691,7 +691,7 @@
private void findAudioSinkFromAudioPolicy(List<AudioDevicePort> sinks) {
sinks.clear();
- ArrayList<AudioDevicePort> devicePorts = new ArrayList<AudioDevicePort>();
+ ArrayList<AudioDevicePort> devicePorts = new ArrayList<>();
if (mAudioManager.listAudioDevicePorts(devicePorts) != AudioManager.SUCCESS) {
return;
}
@@ -707,7 +707,7 @@
if (type == AudioManager.DEVICE_NONE) {
return null;
}
- ArrayList<AudioDevicePort> devicePorts = new ArrayList<AudioDevicePort>();
+ ArrayList<AudioDevicePort> devicePorts = new ArrayList<>();
if (mAudioManager.listAudioDevicePorts(devicePorts) != AudioManager.SUCCESS) {
return null;
}
@@ -900,7 +900,7 @@
mAudioManager.createAudioPatch(
audioPatchArray,
new AudioPortConfig[] { sourceConfig },
- sinkConfigs.toArray(new AudioPortConfig[0]));
+ sinkConfigs.toArray(new AudioPortConfig[sinkConfigs.size()]));
mAudioPatch = audioPatchArray[0];
if (sourceGainConfig != null) {
mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
@@ -1027,12 +1027,12 @@
}
interface Listener {
- public void onStateChanged(String inputId, int state);
- public void onHardwareDeviceAdded(TvInputHardwareInfo info);
- public void onHardwareDeviceRemoved(TvInputHardwareInfo info);
- public void onHdmiDeviceAdded(HdmiDeviceInfo device);
- public void onHdmiDeviceRemoved(HdmiDeviceInfo device);
- public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device);
+ void onStateChanged(String inputId, int state);
+ void onHardwareDeviceAdded(TvInputHardwareInfo info);
+ void onHardwareDeviceRemoved(TvInputHardwareInfo info);
+ void onHdmiDeviceAdded(HdmiDeviceInfo device);
+ void onHdmiDeviceRemoved(HdmiDeviceInfo device);
+ void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device);
}
private class ListenerHandler extends Handler {
@@ -1074,7 +1074,7 @@
}
case HDMI_DEVICE_UPDATED: {
HdmiDeviceInfo info = (HdmiDeviceInfo) msg.obj;
- String inputId = null;
+ String inputId;
synchronized (mLock) {
inputId = mHdmiInputIdMap.get(info.getId());
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 4895d12..51df31f 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -34,6 +34,7 @@
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.Rect;
@@ -112,8 +113,6 @@
private final Context mContext;
private final TvInputHardwareManager mTvInputHardwareManager;
- private final ContentResolver mContentResolver;
-
// A global lock.
private final Object mLock = new Object();
@@ -121,7 +120,7 @@
private int mCurrentUserId = UserHandle.USER_OWNER;
// A map from user id to UserState.
- private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
+ private final SparseArray<UserState> mUserStates = new SparseArray<>();
private final WatchLogHandler mWatchLogHandler;
@@ -129,9 +128,8 @@
super(context);
mContext = context;
- mContentResolver = context.getContentResolver();
- mWatchLogHandler = new WatchLogHandler(mContentResolver, IoThread.get().getLooper());
-
+ mWatchLogHandler = new WatchLogHandler(mContext.getContentResolver(),
+ IoThread.get().getLooper());
mTvInputHardwareManager = new TvInputHardwareManager(context, new HardwareListener());
synchronized (mLock) {
@@ -231,8 +229,7 @@
}
}
- ArrayList<ContentProviderOperation> operations =
- new ArrayList<ContentProviderOperation>();
+ ArrayList<ContentProviderOperation> operations = new ArrayList<>();
String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
String[] selectionArgs = { packageName };
@@ -247,7 +244,8 @@
ContentProviderResult[] results = null;
try {
- results = mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
+ ContentResolver cr = getContentResolverForUser(getChangingUserId());
+ results = cr.applyBatch(TvContract.AUTHORITY, operations);
} catch (RemoteException | OperationApplicationException e) {
Slog.e(TAG, "error in applyBatch", e);
}
@@ -292,7 +290,7 @@
new Intent(TvInputService.SERVICE_INTERFACE),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
userId);
- List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ List<TvInputInfo> inputList = new ArrayList<>();
for (ResolveInfo ri : services) {
ServiceInfo si = ri.serviceInfo;
if (!android.Manifest.permission.BIND_TV_INPUT.equals(si.permission)) {
@@ -325,7 +323,7 @@
userState.packageSet.add(si.packageName);
}
- Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
+ Map<String, TvInputState> inputMap = new HashMap<>();
for (TvInputInfo info : inputList) {
if (DEBUG) {
Slog.d(TAG, "add " + info.getId());
@@ -401,17 +399,18 @@
if (mCurrentUserId == userId) {
return;
}
- // final int oldUserId = mCurrentUserId;
- // TODO: Release services and sessions in the old user state, if needed.
- mCurrentUserId = userId;
+ clearSessionAndServiceStatesLocked(mUserStates.get(mCurrentUserId));
+ mCurrentUserId = userId;
UserState userState = mUserStates.get(userId);
if (userState == null) {
userState = new UserState(mContext, userId);
+ mUserStates.put(userId, userState);
}
- mUserStates.put(userId, userState);
buildTvInputListLocked(userId, null);
buildTvContentRatingSystemListLocked(userId);
+ mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER,
+ getContentResolverForUser(userId)).sendToTarget();
}
}
@@ -421,30 +420,7 @@
if (userState == null) {
return;
}
- // Release created sessions.
- for (SessionState state : userState.sessionStateMap.values()) {
- if (state.session != null) {
- try {
- state.session.release();
- } catch (RemoteException e) {
- Slog.e(TAG, "error in release", e);
- }
- }
- }
- userState.sessionStateMap.clear();
-
- // Unregister all callbacks and unbind all services.
- for (ServiceState serviceState : userState.serviceStateMap.values()) {
- if (serviceState.callback != null) {
- try {
- serviceState.service.unregisterCallback(serviceState.callback);
- } catch (RemoteException e) {
- Slog.e(TAG, "error in unregisterCallback", e);
- }
- }
- mContext.unbindService(serviceState.connection);
- }
- userState.serviceStateMap.clear();
+ clearSessionAndServiceStatesLocked(userState);
// Clear everything else.
userState.inputMap.clear();
@@ -458,6 +434,45 @@
}
}
+ private void clearSessionAndServiceStatesLocked(UserState userState) {
+ // Release created sessions.
+ for (SessionState state : userState.sessionStateMap.values()) {
+ if (state.session != null) {
+ try {
+ state.session.release();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in release", e);
+ }
+ }
+ }
+ userState.sessionStateMap.clear();
+
+ // Unregister all callbacks and unbind all services.
+ for (ServiceState serviceState : userState.serviceStateMap.values()) {
+ if (serviceState.callback != null) {
+ try {
+ serviceState.service.unregisterCallback(serviceState.callback);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in unregisterCallback", e);
+ }
+ }
+ mContext.unbindService(serviceState.connection);
+ }
+ userState.serviceStateMap.clear();
+ }
+
+ private ContentResolver getContentResolverForUser(int userId) {
+ UserHandle user = new UserHandle(userId);
+ Context context;
+ try {
+ context = mContext.createPackageContextAsUser("android", 0, user);
+ } catch (NameNotFoundException e) {
+ Slog.e(TAG, "failed to create package contenxt as user " + user);
+ context = mContext;
+ }
+ return context.getContentResolver();
+ }
+
private UserState getUserStateLocked(int userId) {
UserState userState = mUserStates.get(userId);
if (userState == null) {
@@ -777,7 +792,7 @@
try {
synchronized (mLock) {
UserState userState = getUserStateLocked(resolvedUserId);
- List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ List<TvInputInfo> inputList = new ArrayList<>();
for (TvInputState state : userState.inputMap.values()) {
inputList.add(state.info);
}
@@ -934,7 +949,7 @@
try {
synchronized (mLock) {
UserState userState = getUserStateLocked(resolvedUserId);
- List<String> ratings = new ArrayList<String>();
+ List<String> ratings = new ArrayList<>();
for (TvContentRating rating
: userState.persistentDataStore.getBlockedRatings()) {
ratings.add(rating.flattenToString());
@@ -1012,7 +1027,7 @@
userState.serviceStateMap.put(info.getComponent(), serviceState);
}
// Send a null token immediately while reconnecting.
- if (serviceState.reconnecting == true) {
+ if (serviceState.reconnecting) {
sendSessionTokenToClientLocked(client, inputId, null, null, seq);
return;
}
@@ -1210,7 +1225,6 @@
.sendToTarget();
} catch (RemoteException | SessionNotFoundException e) {
Slog.e(TAG, "error in tune", e);
- return;
}
}
} finally {
@@ -1658,10 +1672,9 @@
UserState userState = getUserStateLocked(resolvedUserId);
if (userState.sessionStateMap.size() == 1) {
return true;
- }
- else if (userState.sessionStateMap.size() == 2) {
+ } else if (userState.sessionStateMap.size() == 2) {
SessionState[] sessionStates = userState.sessionStateMap.values().toArray(
- new SessionState[0]);
+ new SessionState[2]);
// Check if there is a wrapper input.
if (sessionStates[0].hardwareSessionToken != null
|| sessionStates[1].hardwareSessionToken != null) {
@@ -1800,30 +1813,26 @@
private static final class UserState {
// A mapping from the TV input id to its TvInputState.
- private Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
+ private Map<String, TvInputState> inputMap = new HashMap<>();
// A set of all TV input packages.
- private final Set<String> packageSet = new HashSet<String>();
+ private final Set<String> packageSet = new HashSet<>();
// A list of all TV content rating systems defined.
private final List<TvContentRatingSystemInfo>
- contentRatingSystemList = new ArrayList<TvContentRatingSystemInfo>();
+ contentRatingSystemList = new ArrayList<>();
// A mapping from the token of a client to its state.
- private final Map<IBinder, ClientState> clientStateMap =
- new HashMap<IBinder, ClientState>();
+ private final Map<IBinder, ClientState> clientStateMap = new HashMap<>();
// A mapping from the name of a TV input service to its state.
- private final Map<ComponentName, ServiceState> serviceStateMap =
- new HashMap<ComponentName, ServiceState>();
+ private final Map<ComponentName, ServiceState> serviceStateMap = new HashMap<>();
// A mapping from the token of a TV input session to its state.
- private final Map<IBinder, SessionState> sessionStateMap =
- new HashMap<IBinder, SessionState>();
+ private final Map<IBinder, SessionState> sessionStateMap = new HashMap<>();
// A set of callbacks.
- private final Set<ITvInputManagerCallback> callbackSet =
- new HashSet<ITvInputManagerCallback>();
+ private final Set<ITvInputManagerCallback> callbackSet = new HashSet<>();
// The token of a "main" TV input session.
private IBinder mainSessionToken = null;
@@ -1838,7 +1847,7 @@
}
private final class ClientState implements IBinder.DeathRecipient {
- private final List<IBinder> sessionTokens = new ArrayList<IBinder>();
+ private final List<IBinder> sessionTokens = new ArrayList<>();
private IBinder clientToken;
private final int userId;
@@ -1871,11 +1880,11 @@
}
private final class ServiceState {
- private final List<IBinder> sessionTokens = new ArrayList<IBinder>();
+ private final List<IBinder> sessionTokens = new ArrayList<>();
private final ServiceConnection connection;
private final ComponentName component;
private final boolean isHardware;
- private final List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ private final List<TvInputInfo> inputList = new ArrayList<>();
private ITvInputService service;
private ServiceCallback callback;
@@ -2125,13 +2134,13 @@
}
@Override
- public void onSessionCreated(ITvInputSession session, IBinder harewareSessionToken) {
+ public void onSessionCreated(ITvInputSession session, IBinder hardwareSessionToken) {
if (DEBUG) {
Slog.d(TAG, "onSessionCreated(inputId=" + mSessionState.info.getId() + ")");
}
synchronized (mLock) {
mSessionState.session = session;
- mSessionState.hardwareSessionToken = harewareSessionToken;
+ mSessionState.hardwareSessionToken = hardwareSessionToken;
if (session != null && addSessionTokenToClientStateLocked(session)) {
sendSessionTokenToClientLocked(mSessionState.client,
mSessionState.info.getId(), mSessionState.sessionToken, mChannels[0],
@@ -2391,12 +2400,13 @@
// Here the system supplies the database the smallest set of information only that is
// sufficient to consolidate the log entries while minimizing database operations in the
// system service.
- private static final int MSG_LOG_WATCH_START = 1;
- private static final int MSG_LOG_WATCH_END = 2;
+ static final int MSG_LOG_WATCH_START = 1;
+ static final int MSG_LOG_WATCH_END = 2;
+ static final int MSG_SWITCH_CONTENT_RESOLVER = 3;
- private final ContentResolver mContentResolver;
+ private ContentResolver mContentResolver;
- public WatchLogHandler(ContentResolver contentResolver, Looper looper) {
+ WatchLogHandler(ContentResolver contentResolver, Looper looper) {
super(looper);
mContentResolver = contentResolver;
}
@@ -2426,7 +2436,7 @@
mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values);
args.recycle();
- return;
+ break;
}
case MSG_LOG_WATCH_END: {
SomeArgs args = (SomeArgs) msg.obj;
@@ -2441,11 +2451,15 @@
mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values);
args.recycle();
- return;
+ break;
+ }
+ case MSG_SWITCH_CONTENT_RESOLVER: {
+ mContentResolver = (ContentResolver) msg.obj;
+ break;
}
default: {
- Slog.w(TAG, "Unhandled message code: " + msg.what);
- return;
+ Slog.w(TAG, "unhandled message code: " + msg.what);
+ break;
}
}
}
@@ -2559,7 +2573,7 @@
@Override
public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo deviceInfo) {
synchronized (mLock) {
- Integer state = null;
+ Integer state;
switch (deviceInfo.getDevicePowerStatus()) {
case HdmiControlManager.POWER_STATUS_ON:
state = INPUT_STATE_CONNECTED;
@@ -2575,7 +2589,7 @@
break;
}
if (state != null) {
- setStateLocked(inputId, state.intValue(), mCurrentUserId);
+ setStateLocked(inputId, state, mCurrentUserId);
}
}
}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index ac79b36..d4c5f87 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -40,8 +40,6 @@
private boolean mRelroReady32Bit = false;
private boolean mRelroReady64Bit = false;
- private String oldWebViewPackageName = null;
-
private BroadcastReceiver mWebViewUpdatedReceiver;
public WebViewUpdateService(Context context) {
@@ -53,22 +51,9 @@
mWebViewUpdatedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
-
- for (String packageName : WebViewFactory.getWebViewPackageNames()) {
- String webviewPackage = "package:" + packageName;
-
- if (webviewPackage.equals(intent.getDataString())) {
- String usedPackageName =
- WebViewFactory.findPreferredWebViewPackage().packageName;
- // Only trigger update actions if the updated package is the one that
- // will be used, or the one that was in use before the update.
- if (packageName.equals(usedPackageName) ||
- packageName.equals(oldWebViewPackageName)) {
- onWebViewUpdateInstalled();
- oldWebViewPackageName = usedPackageName;
- }
- return;
- }
+ String webviewPackage = "package:" + WebViewFactory.getWebViewPackageName();
+ if (webviewPackage.equals(intent.getDataString())) {
+ onWebViewUpdateInstalled();
}
}
};
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index d7b202d..76baaa7 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -343,7 +343,9 @@
boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
&& !winAnimator.mKeyguardGoingAwayAnimation
&& win.hasDrawnLw()
- && win.mAttachedWindow == null;
+ && win.mAttachedWindow == null
+ && !win.mIsImWindow
+ && displayId == Display.DEFAULT_DISPLAY;
// If the window is already showing and we don't need to apply an existing
// Keyguard exit animation, skip.
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 5064d8f..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 + ","
@@ -1383,10 +1388,21 @@
// Adjust for surface insets.
final LayoutParams attrs = w.getAttrs();
- width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
- height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
- left -= attrs.surfaceInsets.left;
- top -= attrs.surfaceInsets.top;
+ final int displayId = w.getDisplayId();
+ float scale = 1.0f;
+ // Magnification is supported only for the default display.
+ if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+ MagnificationSpec spec =
+ mService.mAccessibilityController.getMagnificationSpecForWindowLocked(w);
+ if (spec != null && !spec.isNop()) {
+ scale = spec.scale;
+ }
+ }
+
+ width += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
+ height += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
+ left -= scale * attrs.surfaceInsets.left;
+ top -= scale * attrs.surfaceInsets.top;
final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
if (surfaceMoved) {
@@ -1652,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/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 3b9cc9d..e257e89 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -48,9 +48,9 @@
static bool wakeup_init = false;
static sem_t wakeup_sem;
-static void wakeup_callback(void)
+static void wakeup_callback(bool success)
{
- ALOGV("In wakeup_callback");
+ ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
int ret = sem_post(&wakeup_sem);
if (ret < 0) {
char buf[80];
@@ -59,10 +59,9 @@
}
}
-static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
- jobjectArray outReasons)
+static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobjectArray outReasons)
{
- if (outIrqs == NULL || outReasons == NULL) {
+ if (outReasons == NULL) {
jniThrowException(env, "java/lang/NullPointerException", "null argument");
return -1;
}
@@ -100,32 +99,47 @@
return -1;
}
- int numOut = env->GetArrayLength(outIrqs);
- ScopedIntArrayRW irqs(env, outIrqs);
-
- ALOGV("Reading up to %d wakeup reasons", numOut);
+ ALOGV("Reading wakeup reasons");
char mergedreason[MAX_REASON_SIZE];
char* mergedreasonpos = mergedreason;
int remainreasonlen = MAX_REASON_SIZE;
- int firstirq = 0;
char reasonline[128];
int i = 0;
- while (fgets(reasonline, sizeof(reasonline), fp) != NULL && i < numOut) {
+ while (fgets(reasonline, sizeof(reasonline), fp) != NULL) {
char* pos = reasonline;
char* endPos;
- // First field is the index.
+ int len;
+ // First field is the index or 'Abort'.
int irq = (int)strtol(pos, &endPos, 10);
- if (pos == endPos) {
- // Ooops.
- ALOGE("Bad reason line: %s", reasonline);
- continue;
+ if (pos != endPos) {
+ // Write the irq number to the merged reason string.
+ len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%d" : ":%d", irq);
+ } else {
+ // The first field is not an irq, it may be the word Abort.
+ const size_t abortPrefixLen = strlen("Abort:");
+ if (strncmp(pos, "Abort:", abortPrefixLen) != 0) {
+ // Ooops.
+ ALOGE("Bad reason line: %s", reasonline);
+ continue;
+ }
+
+ // Write 'Abort' to the merged reason string.
+ len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "Abort" : ":Abort");
+ endPos = pos + abortPrefixLen;
}
pos = endPos;
+
+ if (len >= 0 && len < remainreasonlen) {
+ mergedreasonpos += len;
+ remainreasonlen -= len;
+ }
+
// Skip whitespace; rest of the buffer is the reason string.
while (*pos == ' ') {
pos++;
}
+
// Chop newline at end.
char* endpos = pos;
while (*endpos != 0) {
@@ -135,38 +149,17 @@
}
endpos++;
}
- // For now we are not separating out the first irq.
- // This is because in practice there are always multiple
- // lines of wakeup reasons, so it is better to just treat
- // them all together as a single string.
- if (false && i == 0) {
- firstirq = irq;
- } else {
- int len = snprintf(mergedreasonpos, remainreasonlen,
- i == 0 ? "%d" : ":%d", irq);
- if (len >= 0 && len < remainreasonlen) {
- mergedreasonpos += len;
- remainreasonlen -= len;
- }
- }
- int len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
+
+ len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
if (len >= 0 && len < remainreasonlen) {
mergedreasonpos += len;
remainreasonlen -= len;
}
- // For now it is better to combine all of these in to one entry in the
- // battery history. In the future, it might be nice to figure out a way
- // to efficiently store multiple lines as a single entry in the history.
- //irqs[i] = irq;
- //ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(pos));
- //env->SetObjectArrayElement(outReasons, i, reasonString.get());
- //ALOGV("Wakeup reason #%d: irw %d reason %s", i, irq, pos);
i++;
}
ALOGV("Got %d reasons", i);
if (i > 0) {
- irqs[0] = firstirq;
*mergedreasonpos = 0;
ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(mergedreason));
env->SetObjectArrayElement(outReasons, 0, reasonString.get());
@@ -182,7 +175,7 @@
}
static JNINativeMethod method_table[] = {
- { "nativeWaitWakeup", "([I[Ljava/lang/String;)I", (void*)nativeWaitWakeup },
+ { "nativeWaitWakeup", "([Ljava/lang/String;)I", (void*)nativeWaitWakeup },
};
int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3b62b61..0670cd2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -85,6 +85,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsInternal;
import android.provider.Settings;
@@ -108,7 +109,6 @@
import android.view.inputmethod.InputMethodManager;
import com.android.internal.R;
-import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -225,6 +225,7 @@
private static final Set<String> SECURE_SETTINGS_WHITELIST;
private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
+ private static final Set<String> GLOBAL_SETTINGS_DEPRECATED;
static {
SECURE_SETTINGS_WHITELIST = new HashSet();
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
@@ -240,12 +241,17 @@
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME_ZONE);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DATA_ROAMING);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.MODE_RINGER);
- GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.NETWORK_PREFERENCE);
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);
+
+ GLOBAL_SETTINGS_DEPRECATED = new HashSet();
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.MODE_RINGER);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.NETWORK_PREFERENCE);
+ GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
}
// Keyguard features that when set of a profile will affect the profiles
@@ -3231,15 +3237,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);
@@ -3300,25 +3312,15 @@
}
private void wipeDataLocked(boolean wipeExtRequested, String reason) {
- // TODO: wipe all public volumes on device
-
- // If the SD card is encrypted and non-removable, we have to force a wipe.
- boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
-
- // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
- if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
- Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
- intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
- intent.putExtra(Intent.EXTRA_REASON, reason);
- intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
- mWakeLock.acquire(10000);
- mContext.startService(intent);
- } else {
- try {
- RecoverySystem.rebootWipeUserData(mContext, reason);
- } catch (IOException | SecurityException e) {
- Slog.w(LOG_TAG, "Failed requesting data wipe", e);
- }
+ if (wipeExtRequested) {
+ StorageManager sm = (StorageManager) mContext.getSystemService(
+ Context.STORAGE_SERVICE);
+ sm.wipeAdoptableDisks();
+ }
+ try {
+ RecoverySystem.rebootWipeUserData(mContext, reason);
+ } catch (IOException | SecurityException e) {
+ Slog.w(LOG_TAG, "Failed requesting data wipe", e);
}
}
@@ -4207,16 +4209,11 @@
throw new SecurityException("clearDeviceOwner can only be called by the device owner");
}
synchronized (this) {
- long ident = Binder.clearCallingIdentity();
- try {
- clearUserRestrictions(new UserHandle(UserHandle.USER_OWNER));
- if (mDeviceOwner != null) {
- mDeviceOwner.clearDeviceOwner();
- mDeviceOwner.writeOwnerFile();
- updateDeviceOwnerLocked();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
+ clearUserPoliciesLocked(new UserHandle(UserHandle.USER_OWNER));
+ if (mDeviceOwner != null) {
+ mDeviceOwner.clearDeviceOwner();
+ mDeviceOwner.writeOwnerFile();
+ updateDeviceOwnerLocked();
}
}
}
@@ -4367,30 +4364,39 @@
return;
}
UserHandle callingUser = Binder.getCallingUserHandle();
- int userId = callingUser.getIdentifier();
// Check if this is the profile owner who is calling
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
synchronized (this) {
- // Reset some of the profile-owner policies
- DevicePolicyData policy = getUserData(userId);
- policy.mPermissionPolicy = DevicePolicyManager.PERMISSION_POLICY_PROMPT;
- policy.mDelegatedCertInstallerPackage = null;
- policy.mStatusBarDisabled = false;
- saveSettingsLocked(userId);
-
- long ident = Binder.clearCallingIdentity();
- try {
- clearUserRestrictions(callingUser);
- if (mDeviceOwner != null) {
- mDeviceOwner.removeProfileOwner(userId);
- mDeviceOwner.writeOwnerFile();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
+ clearUserPoliciesLocked(callingUser);
+ if (mDeviceOwner != null) {
+ mDeviceOwner.removeProfileOwner(callingUser.getIdentifier());
+ mDeviceOwner.writeOwnerFile();
}
}
}
+ private void clearUserPoliciesLocked(UserHandle userHandle) {
+ int userId = userHandle.getIdentifier();
+ // Reset some of the user-specific policies
+ DevicePolicyData policy = getUserData(userId);
+ policy.mPermissionPolicy = DevicePolicyManager.PERMISSION_POLICY_PROMPT;
+ policy.mDelegatedCertInstallerPackage = null;
+ policy.mStatusBarDisabled = false;
+ saveSettingsLocked(userId);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ clearUserRestrictions(userHandle);
+ AppGlobals.getPackageManager().updatePermissionFlagsForAllApps(
+ PackageManager.FLAG_PERMISSION_POLICY_FIXED,
+ 0 /* flagValues */, userHandle.getIdentifier());
+ } catch (RemoteException re) {
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+
private void clearUserRestrictions(UserHandle userHandle) {
AudioManager audioManager =
(AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
@@ -5953,14 +5959,16 @@
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ // Some settings are no supported any more. However we do not want to throw a
+ // SecurityException to avoid breaking apps.
+ if (GLOBAL_SETTINGS_DEPRECATED.contains(setting)) {
+ Log.i(LOG_TAG, "Global setting no longer supported: " + setting);
+ return;
+ }
+
if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
- // BLUETOOTH_ON and WIFI_ON used to be supported but not any more. We do not want to
- // throw a SecurityException not to break apps.
- if (!Settings.Global.BLUETOOTH_ON.equals(setting)
- && !Settings.Global.WIFI_ON.equals(setting)) {
- throw new SecurityException(String.format(
- "Permission denial: device owners cannot update %1$s", setting));
- }
+ throw new SecurityException(String.format(
+ "Permission denial: device owners cannot update %1$s", setting));
}
if (Settings.Global.STAY_ON_WHILE_PLUGGED_IN.equals(setting)) {
@@ -6383,21 +6391,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/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 29c65db..76226b4 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -292,7 +292,7 @@
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
- mSystemContext.setTheme(android.R.style.Theme_Material_DayNight_DarkActionBar);
+ mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index b58c2e2..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;
@@ -134,6 +135,7 @@
private final NetworkInfo mNetworkInfo;
private final NetworkCapabilities mNetworkCapabilities;
private final Thread mThread;
+ private int mScore;
private NetworkAgent mNetworkAgent;
MockNetworkAgent(int transport) {
@@ -142,13 +144,12 @@
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.addTransportType(transport);
- final int score;
switch (transport) {
case TRANSPORT_WIFI:
- score = 60;
+ mScore = 60;
break;
case TRANSPORT_CELLULAR:
- score = 50;
+ mScore = 50;
break;
default:
throw new UnsupportedOperationException("unimplemented network type");
@@ -159,7 +160,7 @@
Looper.prepare();
mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext,
"Mock" + typeName, mNetworkInfo, mNetworkCapabilities,
- new LinkProperties(), score, new NetworkMisc()) {
+ new LinkProperties(), mScore, new NetworkMisc()) {
public void unwanted() {}
};
initComplete.open();
@@ -167,7 +168,12 @@
}
};
mThread.start();
- initComplete.block();
+ waitFor(initComplete);
+ }
+
+ public void adjustScore(int change) {
+ mScore += change;
+ mNetworkAgent.sendNetworkScore(mScore);
}
/**
@@ -209,7 +215,7 @@
if (validated) {
// Wait for network to validate.
- validatedCv.block();
+ waitFor(validatedCv);
mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
}
@@ -330,6 +336,10 @@
public boolean get();
}
+ /**
+ * Wait up to 500ms for {@code criteria.get()} to become true, polling.
+ * Fails if 500ms goes by before {@code criteria.get()} to become true.
+ */
static private void waitFor(Criteria criteria) {
int delays = 0;
while (!criteria.get()) {
@@ -341,6 +351,26 @@
}
}
+ /**
+ * Wait up to 500ms for {@code conditonVariable} to open.
+ * Fails if 500ms goes by before {@code conditionVariable} opens.
+ */
+ static private void waitFor(ConditionVariable conditionVariable) {
+ assertTrue(conditionVariable.block(500));
+ }
+
+ /**
+ * This should only be used to verify that nothing happens, in other words that no unexpected
+ * changes occur. It should never be used to wait for a specific positive signal to occur.
+ */
+ private void shortSleep() {
+ // TODO: Instead of sleeping, instead wait for all message loops to idle.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ }
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -431,7 +461,7 @@
// Test bringing up validated cellular.
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
assertEquals(2, mCm.getAllNetworks().length);
assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
@@ -441,7 +471,7 @@
// Test bringing up validated WiFi.
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
assertEquals(2, mCm.getAllNetworks().length);
assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
@@ -459,7 +489,7 @@
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@@ -469,38 +499,32 @@
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up unvalidated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
+ shortSleep();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test cellular disconnect.
mCellNetworkAgent.disconnect();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
+ shortSleep();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up validated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
cv = waitForConnectivityBroadcasts(2);
mCellNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
cv = waitForConnectivityBroadcasts(2);
mCellNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@@ -510,27 +534,209 @@
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@LargeTest
+ public void testCellularOutscoresWeakWifi() throws Exception {
+ // Test bringing up validated cellular.
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent.connect(true);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_CELLULAR);
+ // Test bringing up validated WiFi.
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.connect(true);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_WIFI);
+ // Test WiFi getting really weak.
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.adjustScore(-11);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_CELLULAR);
+ // Test WiFi restoring signal strength.
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.adjustScore(11);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_WIFI);
+ mCellNetworkAgent.disconnect();
+ mWiFiNetworkAgent.disconnect();
+ }
+
+ enum CallbackState {
+ NONE,
+ AVAILABLE,
+ LOSING,
+ LOST
+ }
+
+ private class TestNetworkCallback extends NetworkCallback {
+ private final ConditionVariable mConditionVariable = new ConditionVariable();
+ private CallbackState mLastCallback = CallbackState.NONE;
+
+ public void onAvailable(Network network) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.AVAILABLE;
+ mConditionVariable.open();
+ }
+
+ public void onLosing(Network network, int maxMsToLive) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.LOSING;
+ mConditionVariable.open();
+ }
+
+ public void onLost(Network network) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.LOST;
+ mConditionVariable.open();
+ }
+
+ ConditionVariable getConditionVariable() {
+ mLastCallback = CallbackState.NONE;
+ mConditionVariable.close();
+ return mConditionVariable;
+ }
+
+ CallbackState getLastCallback() {
+ return mLastCallback;
+ }
+ }
+
+ @LargeTest
+ public void testStateChangeNetworkCallbacks() throws Exception {
+ final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
+ final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI).build();
+ final NetworkRequest cellRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).build();
+ mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+ mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+
+ // Test unvalidated networks
+ ConditionVariable cellCv = cellNetworkCallback.getConditionVariable();
+ ConditionVariable wifiCv = wifiNetworkCallback.getConditionVariable();
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(false);
+ waitFor(cellCv);
+ assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // This should not trigger spurious onAvailable() callbacks, b/21762680.
+ mCellNetworkAgent.adjustScore(-1);
+ shortSleep();
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false);
+ waitFor(wifiCv);
+ assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.disconnect();
+ waitFor(wifiCv);
+ assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent.disconnect();
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ waitFor(cv);
+
+ // Test validated networks
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // Our method for faking successful validation generates an additional callback, so wait
+ // for broadcast instead.
+ cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(true);
+ waitFor(cv);
+ waitFor(cellCv);
+ assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // This should not trigger spurious onAvailable() callbacks, b/21762680.
+ mCellNetworkAgent.adjustScore(-1);
+ shortSleep();
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // Our method for faking successful validation generates an additional callback, so wait
+ // for broadcast instead.
+ cv = waitForConnectivityBroadcasts(1);
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true);
+ waitFor(cv);
+ waitFor(wifiCv);
+ assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOSING, cellNetworkCallback.getLastCallback());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ mWiFiNetworkAgent.disconnect();
+ waitFor(wifiCv);
+ assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ mCellNetworkAgent.disconnect();
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ }
+
+ @LargeTest
public void testNetworkFactoryRequests() throws Exception {
NetworkCapabilities filter = new NetworkCapabilities();
filter.addCapability(NET_CAPABILITY_INTERNET);
@@ -541,7 +747,7 @@
testFactory.setScoreFilter(40);
ConditionVariable cv = testFactory.getNetworkStartedCV();
testFactory.register();
- cv.block();
+ waitFor(cv);
assertEquals(1, testFactory.getMyRequestCount());
assertEquals(true, testFactory.getMyStartRequested());
@@ -550,10 +756,10 @@
cv = waitForConnectivityBroadcasts(1);
ConditionVariable cvRelease = testFactory.getNetworkStoppedCV();
testAgent.connect(true);
- cv.block();
+ waitFor(cv);
// part of the bringup makes another network request and then releases it
// wait for the release
- cvRelease.block();
+ waitFor(cvRelease);
assertEquals(false, testFactory.getMyStartRequested());
testFactory.waitForNetworkRequests(1);
@@ -579,7 +785,7 @@
// drop the higher scored network
cv = waitForConnectivityBroadcasts(1);
testAgent.disconnect();
- cv.block();
+ waitFor(cv);
assertEquals(1, testFactory.getMyRequestCount());
assertEquals(true, testFactory.getMyStartRequested());
@@ -587,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 {
@@ -605,7 +835,7 @@
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// // verify that both routes were added
// int mobileNetId = mMobile.tracker.getNetwork().netId;
@@ -625,7 +855,7 @@
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// reset(mNetManager);
//
@@ -641,7 +871,7 @@
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// // verify that wifi routes added, and teardown requested
// int wifiNetId = mWifi.tracker.getNetwork().netId;
@@ -660,7 +890,7 @@
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3767fce..c49a5f9 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -31,6 +31,7 @@
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -69,8 +70,8 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
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;
@@ -117,6 +118,8 @@
static final int MSG_CHECK_IDLE_STATES = 5;
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;
@@ -133,6 +136,7 @@
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
+ boolean mAppIdleEnabled;
boolean mAppIdleParoled;
private boolean mScreenOn;
private long mLastAppIdleParoledTime;
@@ -170,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();
}
@@ -181,7 +190,6 @@
mRealTimeSnapshot = SystemClock.elapsedRealtime();
mSystemTimeSnapshot = System.currentTimeMillis();
-
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
@@ -306,7 +314,7 @@
mLastAppIdleParoledTime = checkAndGetTimeLocked();
postNextParoleTimeout();
}
- postCheckIdleStates(UserHandle.USER_ALL);
+ postParoleStateChanged();
}
}
}
@@ -331,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) {
@@ -583,6 +601,29 @@
}
}
+ void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
+ // Get sync adapters for the authority
+ String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
+ authority, userId);
+ for (String packageName: packages) {
+ // Only force the sync adapters to active if the provider is not in the same package and
+ // the sync adapter is a system package.
+ try {
+ PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(
+ packageName, 0, userId);
+ if (pi == null || pi.applicationInfo == null
+ || !pi.applicationInfo.isSystemApp()) {
+ continue;
+ }
+ if (!packageName.equals(providerPkgName)) {
+ forceIdleState(packageName, userId, false);
+ }
+ } catch (RemoteException re) {
+ // Shouldn't happen
+ }
+ }
+ }
+
/**
* Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
* then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
@@ -605,7 +646,7 @@
timeNow - (idle ? mAppIdleWallclockThresholdMillis : 0) - 5000);
// Inform listeners if necessary
if (previouslyIdle != idle) {
- // Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
+ // Slog.d(TAG, "Informing listeners of out-of-idle " + packageName);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ idle ? 1 : 0, packageName));
if (!idle) {
@@ -722,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;
@@ -744,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 {
@@ -808,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;
}
@@ -872,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();
}
}
@@ -916,6 +980,19 @@
setAppIdleParoled(false);
break;
+ case MSG_REPORT_CONTENT_PROVIDER_USAGE:
+ SomeArgs args = (SomeArgs) msg.obj;
+ reportContentProviderUsage((String) args.arg1, // authority name
+ (String) args.arg2, // package name
+ (int) args.arg3); // userId
+ args.recycle();
+ break;
+
+ case MSG_PAROLE_STATE_CHANGED:
+ if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled);
+ informParoleStateChanged();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -1067,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);
}
@@ -1177,11 +1254,26 @@
}
@Override
+ public void reportContentProviderUsage(String name, String packageName, int userId) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = name;
+ args.arg2 = packageName;
+ args.arg3 = userId;
+ mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args)
+ .sendToTarget();
+ }
+
+ @Override
public boolean isAppIdle(String packageName, int userId) {
return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
}
@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
@@ -1192,6 +1284,7 @@
@Override
public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) {
UsageStatsService.this.addListener(listener);
+ listener.onParoleStateChanged(isAppIdleParoleOn());
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index fafe44a..cde87bd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -26,6 +26,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
@@ -57,6 +58,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -83,6 +85,21 @@
mDbHelper = new DatabaseHelper(context);
mSoundTriggerHelper = new SoundTriggerHelper(context);
mServiceStub = new VoiceInteractionManagerServiceStub();
+
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setVoiceInteractionPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ mServiceStub.initForUser(userId);
+ ComponentName interactor = mServiceStub.getCurInteractor(userId);
+ if (interactor != null) {
+ return new String[] {interactor.getPackageName()};
+ }
+ return null;
+ }
+ });
}
@Override
@@ -416,6 +433,11 @@
+ " user=" + userHandle);
}
+ void resetCurAssistant(int userHandle) {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSISTANT, null, userHandle);
+ }
+
@Override
public void showSession(IVoiceInteractionService service, Bundle args, int flags) {
synchronized (this) {
@@ -880,6 +902,7 @@
}
setCurInteractor(null, userHandle);
setCurRecognizer(null, userHandle);
+ resetCurAssistant(userHandle);
initForUser(userHandle);
switchImplementationIfNeededLocked(true);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index acd484d..af0ddbe 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -139,7 +139,7 @@
IVoiceInteractionSessionShowCallback showCallback) {
if (mActiveSession == null) {
mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
- mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid);
+ mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler);
}
return mActiveSession.showLocked(args, flags, showCallback);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 47a230a..bd043ac 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -32,6 +32,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -48,6 +49,8 @@
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -63,6 +66,7 @@
final Context mContext;
final Callback mCallback;
final int mCallingUid;
+ final Handler mHandler;
final IActivityManager mAm;
final IWindowManager mIWindowManager;
final AppOpsManager mAppOps;
@@ -141,13 +145,14 @@
};
public VoiceInteractionSessionConnection(Object lock, ComponentName component, int user,
- Context context, Callback callback, int callingUid) {
+ Context context, Callback callback, int callingUid, Handler handler) {
mLock = lock;
mSessionComponentName = component;
mUser = user;
mContext = context;
mCallback = callback;
mCallingUid = callingUid;
+ mHandler = handler;
mAm = ActivityManagerNative.getDefault();
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -188,16 +193,27 @@
new UserHandle(mUser));
}
mShown = true;
- boolean allDataEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0;
+ boolean isScreenCaptureAllowed = true;
+ try {
+ isScreenCaptureAllowed = mAm.isScreenCaptureAllowedOnCurrentActivity();
+ } catch (RemoteException e) {
+ }
+ boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0
+ && isScreenCaptureAllowed;
+ boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0
+ && isScreenCaptureAllowed;
mShowArgs = args;
mShowFlags = flags;
mHaveAssistData = false;
+ boolean needDisclosure = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
- && allDataEnabled) {
+ && structureEnabled) {
try {
+ needDisclosure = true;
mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
mAssistReceiver);
} catch (RemoteException e) {
@@ -213,8 +229,9 @@
if ((flags& VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
- && allDataEnabled) {
+ && screenshotEnabled) {
try {
+ needDisclosure = true;
mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
} catch (RemoteException e) {
}
@@ -225,6 +242,9 @@
} else {
mScreenshot = null;
}
+ if (needDisclosure) {
+ mHandler.post(mShowAssistDisclosureRunnable);
+ }
if (mSession != null) {
try {
mSession.show(mShowArgs, mShowFlags, showCallback);
@@ -483,4 +503,15 @@
pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
}
}
+
+ private Runnable mShowAssistDisclosureRunnable = new Runnable() {
+ @Override
+ public void run() {
+ StatusBarManagerInternal statusBarInternal = LocalServices.getService(
+ StatusBarManagerInternal.class);
+ if (statusBarInternal != null) {
+ statusBarInternal.showAssistDisclosure();
+ }
+ }
+ };
};
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 91566f8..721b718 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -40,7 +40,8 @@
import java.util.concurrent.ConcurrentHashMap;
/**
- * Represents a connection to a remote endpoint that carries voice traffic.
+ * Represents a phone call or connection to a remote endpoint that carries voice and/or video
+ * traffic.
* <p>
* Implementations create a custom subclass of {@code Connection} and return it to the framework
* as the return value of
@@ -53,21 +54,52 @@
*/
public abstract class Connection extends Conferenceable {
+ /**
+ * The connection is initializing. This is generally the first state for a {@code Connection}
+ * returned by a {@link ConnectionService}.
+ */
public static final int STATE_INITIALIZING = 0;
+ /**
+ * The connection is new and not connected.
+ */
public static final int STATE_NEW = 1;
+ /**
+ * An incoming connection is in the ringing state. During this state, the user's ringer or
+ * vibration feature will be activated.
+ */
public static final int STATE_RINGING = 2;
+ /**
+ * An outgoing connection is in the dialing state. In this state the other party has not yet
+ * answered the call and the user traditionally hears a ringback tone.
+ */
public static final int STATE_DIALING = 3;
+ /**
+ * A connection is active. Both parties are connected to the call and can actively communicate.
+ */
public static final int STATE_ACTIVE = 4;
+ /**
+ * A connection is on hold.
+ */
public static final int STATE_HOLDING = 5;
+ /**
+ * A connection has been disconnected. This is the final state once the user has been
+ * disconnected from a call either locally, remotely or by an error in the service.
+ */
public static final int STATE_DISCONNECTED = 6;
- /** Connection can currently be put on hold or unheld. */
+ /**
+ * Connection can currently be put on hold or unheld. This is distinct from
+ * {@link #CAPABILITY_SUPPORT_HOLD} in that although a connection may support 'hold' most times,
+ * it does not at the moment support the function. This can be true while the call is in the
+ * state {@link #STATE_DIALING}, for example. During this condition, an in-call UI may
+ * display a disabled 'hold' button.
+ */
public static final int CAPABILITY_HOLD = 0x00000001;
/** Connection supports the hold feature. */
@@ -1067,6 +1099,9 @@
@SystemApi
@Deprecated
public final AudioState getAudioState() {
+ if (mCallAudioState == null) {
+ return null;
+ }
return new AudioState(mCallAudioState);
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 1e8ae88..d2e7a74 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -41,8 +41,8 @@
import java.util.concurrent.ConcurrentHashMap;
/**
- * {@code ConnectionService} is an abstract service that should be implemented by any app which can
- * make phone calls and want those calls to be integrated into the built-in phone app.
+ * An abstract service that should be implemented by any apps which can make phone calls (VoIP or
+ * otherwise) and want those calls to be integrated into the built-in phone app.
* Once implemented, the {@code ConnectionService} needs two additional steps before it will be
* integrated into the phone app:
* <p>
@@ -62,7 +62,7 @@
* <br/>
* See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
* <p>
- * Once registered and enabled by the user in the dialer settings, telecom will bind to a
+ * Once registered and enabled by the user in the phone app settings, telecom will bind to a
* {@code ConnectionService} implementation when it wants that {@code ConnectionService} to place
* a call or the service has indicated that is has an incoming call through
* {@link TelecomManager#addNewIncomingCall}. The {@code ConnectionService} can then expect a call
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index fb985ce..19c613d 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -39,7 +39,24 @@
/**
* This service is implemented by any app that wishes to provide the user-interface for managing
* phone calls. Telecom binds to this service while there exists a live (active or incoming) call,
- * and uses it to notify the in-call app of any live and and recently disconnected calls.
+ * and uses it to notify the in-call app of any live and recently disconnected calls. An app must
+ * first be set as the default phone app (See {@link TelecomManager#getDefaultDialerPackage()})
+ * before the telecom service will bind to its {@code InCallService} implementation.
+ * <p>
+ * Below is an example manifest registration for an {@code InCallService}. The meta-data
+ * ({@link TelecomManager#METADATA_IN_CALL_SERVICE_UI}) indicates that this particular
+ * {@code InCallService} implementation intends to replace the built-in in-call UI.
+ * <pre>
+ * {@code
+ * <service android:name="your.package.YourInCallServiceImplementation"
+ * android:permission="android.permission.BIND_IN_CALL_SERVICE">
+ * <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
+ * <intent-filter>
+ * <action android:name="android.telecom.InCallService"/>
+ * </intent-filter>
+ * </service>
+ * }
+ * </pre>
*/
public abstract class InCallService extends Service {
@@ -231,7 +248,7 @@
}
/**
- * Obtains the current list of {@code Call}s to be displayed by this in-call experience.
+ * Obtains the current list of {@code Call}s to be displayed by this in-call service.
*
* @return A list of the relevant {@code Call}s.
*/
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index a25d327..df6fa2e 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -412,7 +412,7 @@
* bit mask.
*
* @param capability The capabilities to check.
- * @return {@code True} if the phone account has the capability.
+ * @return {@code true} if the phone account has the capability.
*/
public boolean hasCapabilities(int capability) {
return (mCapabilities & capability) == capability;
@@ -455,9 +455,10 @@
}
/**
- * Indicates whether the user has enabled this phone account or not {@code PhoneAccounts}.
+ * Indicates whether the user has enabled this {@code PhoneAccount} or not. This value is only
+ * populated for {@code PhoneAccount}s returned by {@link TelecomManager#getPhoneAccount}.
*
- * @return The {@code true} if the account is enabled by the user, {@code false} otherwise.
+ * @return {@code true} if the account is enabled by the user, {@code false} otherwise.
*/
public boolean isEnabled() {
return mIsEnabled;
@@ -468,7 +469,7 @@
* scheme.
*
* @param uriScheme The URI scheme to check.
- * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the
+ * @return {@code true} if the {@code PhoneAccount} supports calls to/from addresses with the
* specified URI scheme.
*/
public boolean supportsUriScheme(String uriScheme) {
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index c2261c37..ae5cd46 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -32,25 +32,90 @@
import java.util.concurrent.CopyOnWriteArraySet;
/**
- * A conference provided to a {@link ConnectionService} by another {@code ConnectionService}
- * running in a different process.
+ * A conference provided to a {@link ConnectionService} by another {@code ConnectionService} through
+ * {@link ConnectionService#conferenceRemoteConnections}. Once created, a {@code RemoteConference}
+ * can be used to control the conference call or monitor changes through
+ * {@link RemoteConnection.Callback}.
*
* @see ConnectionService#onRemoteConferenceAdded
*/
public final class RemoteConference {
+ /**
+ * Callback base class for {@link RemoteConference}.
+ */
public abstract static class Callback {
+ /**
+ * Invoked when the state of this {@code RemoteConferece} has changed. See
+ * {@link #getState()}.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param oldState The previous state of the {@code RemoteConference}.
+ * @param newState The new state of the {@code RemoteConference}.
+ */
public void onStateChanged(RemoteConference conference, int oldState, int newState) {}
+
+ /**
+ * Invoked when this {@code RemoteConference} is disconnected.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param disconnectCause The ({@see DisconnectCause}) associated with this failed
+ * conference.
+ */
public void onDisconnected(RemoteConference conference, DisconnectCause disconnectCause) {}
+
+ /**
+ * Invoked when a {@link RemoteConnection} is added to the conference call.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connection The {@link RemoteConnection} being added.
+ */
public void onConnectionAdded(RemoteConference conference, RemoteConnection connection) {}
+
+ /**
+ * Invoked when a {@link RemoteConnection} is removed from the conference call.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connection The {@link RemoteConnection} being removed.
+ */
public void onConnectionRemoved(RemoteConference conference, RemoteConnection connection) {}
+
+ /**
+ * Indicates that the call capabilities of this {@code RemoteConference} have changed.
+ * See {@link #getConnectionCapabilities()}.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param connectionCapabilities The new capabilities of the {@code RemoteConference}.
+ */
public void onConnectionCapabilitiesChanged(
RemoteConference conference,
int connectionCapabilities) {}
+
+ /**
+ * Invoked when the set of {@link RemoteConnection}s which can be added to this conference
+ * call have changed.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param conferenceableConnections The list of conferenceable {@link RemoteConnection}s.
+ */
public void onConferenceableConnectionsChanged(
RemoteConference conference,
List<RemoteConnection> conferenceableConnections) {}
+
+ /**
+ * Indicates that this {@code RemoteConference} has been destroyed. No further requests
+ * should be made to the {@code RemoteConference}, and references to it should be cleared.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ */
public void onDestroyed(RemoteConference conference) {}
+
+ /**
+ * Handles changes to the {@code RemoteConference} extras.
+ *
+ * @param conference The {@code RemoteConference} invoking this method.
+ * @param extras The extras containing other information associated with the conference.
+ */
public void onExtrasChanged(RemoteConference conference, @Nullable Bundle extras) {}
}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 8f7b82f..f960959 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -45,6 +45,9 @@
*/
public final class RemoteConnection {
+ /**
+ * Callback base class for {@link RemoteConnection}.
+ */
public static abstract class Callback {
/**
* Invoked when the state of this {@code RemoteConnection} has changed. See
@@ -200,7 +203,7 @@
RemoteConference conference) {}
/**
- * Handles changes to the {@code RemoteConference} extras.
+ * Handles changes to the {@code RemoteConnection} extras.
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param extras The extras containing other information associated with the connection.
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 0cd8c19..a30e1c0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -67,11 +67,19 @@
public static final String ACTION_NEW_UNKNOWN_CALL = "android.telecom.action.NEW_UNKNOWN_CALL";
/**
- * The {@link android.content.Intent} action used to configure a
- * {@link android.telecom.ConnectionService}.
+ * An {@link android.content.Intent} action sent by the telecom framework to start a
+ * configuration dialog for a registered {@link PhoneAccount}. There is no default dialog
+ * and each app that registers a {@link PhoneAccount} should provide one if desired.
+ * <p>
+ * A user can access the list of enabled {@link android.telecom.PhoneAccount}s through the Phone
+ * app's settings menu. For each entry, the settings app will add a click action. When
+ * triggered, the click-action will start this intent along with the extra
+ * {@link #EXTRA_PHONE_ACCOUNT_HANDLE} to indicate the {@link PhoneAccount} to configure. If the
+ * {@link PhoneAccount} package does not register an {@link android.app.Activity} for this
+ * intent, then it will not be sent.
*/
- public static final String ACTION_CONNECTION_SERVICE_CONFIGURE =
- "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+ public static final String ACTION_CONFIGURE_PHONE_ACCOUNT =
+ "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
/**
* The {@link android.content.Intent} action used to show the call accessibility settings page.
@@ -187,7 +195,7 @@
* Optional extra for {@link android.content.Intent#ACTION_CALL} and
* {@link android.content.Intent#ACTION_DIAL} {@code Intent} containing a {@link Bundle}
* which contains metadata about the call. This {@link Bundle} will be saved into
- * {@code Call.Details}.
+ * {@code Call.Details} and passed to the {@link ConnectionService} when placing the call.
*/
public static final String EXTRA_OUTGOING_CALL_EXTRAS =
"android.telecom.extra.OUTGOING_CALL_EXTRAS";
@@ -256,6 +264,14 @@
public static final String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
/**
+ * A boolean meta-data value indicating whether an {@link InCallService} implements an
+ * in-call user interface. Dialer implementations (see {@link #getDefaultDialerPackage()}) which
+ * would also like to replace the in-call interface should set this meta-data to {@code true} in
+ * the manifest registration of their {@link InCallService}.
+ */
+ public static final String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
+
+ /**
* The dual tone multi-frequency signaling character sent to indicate the dialing system should
* pause for a predefined period.
*/
@@ -477,39 +493,6 @@
}
/**
- * Sets the SIM call manager to the specified phone account.
- *
- * @param accountHandle The phone account handle of the account to set as the sim call manager.
- * @hide
- */
- public void setSimCallManager(PhoneAccountHandle accountHandle) {
- try {
- if (isServiceConnected()) {
- getTelecomService().setSimCallManager(accountHandle);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecomService#setSimCallManager");
- }
- }
-
- /**
- * Returns the list of registered SIM call managers.
- *
- * @return List of registered SIM call managers.
- * @hide
- */
- public List<PhoneAccountHandle> getSimCallManagers() {
- try {
- if (isServiceConnected()) {
- return getTelecomService().getSimCallManagers(mContext.getOpPackageName());
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecomService#getSimCallManagers");
- }
- return new ArrayList<>();
- }
-
- /**
* Returns the current connection manager. Apps must be prepared for this method to return
* {@code null}, indicating that there currently exists no user-chosen default
* {@code PhoneAccount}.
@@ -1199,6 +1182,14 @@
* telecomManager.placeCall(uri, extras);
* </pre>
*
+ * The following keys are supported in the supplied extras.
+ * <ul>
+ * <li>{@link #EXTRA_OUTGOING_CALL_EXTRAS}</li>
+ * <li>{@link #EXTRA_PHONE_ACCOUNT_HANDLE}</li>
+ * <li>{@link #EXTRA_START_CALL_WITH_SPEAKERPHONE}</li>
+ * <li>{@link #EXTRA_START_CALL_WITH_VIDEO_STATE}</li>
+ * </ul>
+ *
* @param address The address to make the call to.
* @param extras Bundle of extras to use with the call.
*/
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index ea6a74a..fb0f6da 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -93,16 +93,6 @@
PhoneAccountHandle getSimCallManager();
/**
- * @see TelecomServiceImpl#setSimCallManager
- */
- void setSimCallManager(in PhoneAccountHandle account);
-
- /**
- * @see TelecomServiceImpl#getSimCallManagers
- */
- List<PhoneAccountHandle> getSimCallManagers(String callingPackage);
-
- /**
* @see TelecomServiceImpl#registerPhoneAccount
*/
void registerPhoneAccount(in PhoneAccount metadata);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0eb94b8..e861668 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -84,7 +84,7 @@
* from config.xml under apps/Contacts.
*/
public static final String
- KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
+ KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
/** Flag indicating if dtmf tone type is enabled */
public static final String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
@@ -211,6 +211,19 @@
KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
/**
+ * Override the platform's notion of a network operator being considered non roaming.
+ * If true all networks are considered as home network a.k.a non-roaming. When false,
+ * the 2 pairs of CMDA and GSM roaming/non-roaming arrays are consulted.
+ *
+ * @see KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY
+ * @see KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY
+ * @see KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY
+ * @see KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY
+ */
+ public static final String
+ KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
+
+ /**
* Flag specifying whether VoLTE should be available for carrier, independent of carrier
* provisioning. If false: hard disabled. If true: then depends on carrier provisioning,
* availability, etc.
@@ -218,20 +231,34 @@
public static final String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
/**
+ * Flag specifying whether video telephony is available for carrier. If false: hard disabled.
+ * If true: then depends on carrier provisioning, availability, etc.
+ */
+ public static final String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
+
+ /**
* Flag specifying whether WFC over IMS should be available for carrier: independent of
* carrier provisioning. If false: hard disabled. If true: then depends on carrier
* provisioning, availability etc.
*/
public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
- /** Flag specifying whether VoLTE availability is based on provisioning. */
- public static final String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ /** Flag specifying whether provisioning is required for VOLTE. */
+ public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
+ = "carrier_volte_provisioning_required_bool";
/** Flag specifying whether VoLTE TTY is supported. */
public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
= "carrier_volte_tty_supported_bool";
/**
+ * Flag specifying whether IMS service can be turned off. If false then the service will not be
+ * turned-off completely, but individual features can be disabled.
+ */
+ public static final String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL
+ = "carrier_allow_turnoff_ims_bool";
+
+ /**
* If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
* this is the value that should be used instead. A configuration value of
* RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default
@@ -249,32 +276,24 @@
/* The following 3 fields are related to carrier visual voicemail. */
/**
- * The carrier number MO sms messages are sent to.
- *
- * @hide
+ * The carrier number mobile outgoing (MO) sms messages are sent to.
*/
public static final String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
/**
- * The port through which the MO sms messages are sent through.
- *
- * @hide
+ * The port through which the mobile outgoing (MO) sms messages are sent through.
*/
public static final String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
/**
* The type of visual voicemail protocol the carrier adheres to. See {@link TelephonyManager}
* for possible values. For example {@link TelephonyManager#VVM_TYPE_OMTP}.
- *
- * @hide
*/
public static final String KEY_VVM_TYPE_STRING = "vvm_type_string";
/**
* The package name of the carrier's visual voicemail app to ensure that dialer visual voicemail
* and carrier visual voicemail are not active at the same time.
- *
- * @hide
*/
public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
@@ -306,6 +325,14 @@
public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING =
"ci_action_on_sys_update_extra_val_string";
+ /**
+ * If this is true, the SIM card (through Customer Service Profile EF file) will be able to
+ * prevent manual operator selection. If false, this SIM setting will be ignored and manual
+ * operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
+ * information
+ */
+ public static final String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
+
// These variables are used by the MMS service and exposed through another API, {@link
// SmsManager}. The variable names and string values are copied from there.
public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -352,9 +379,11 @@
sDefaults.putBoolean(KEY_AUTO_RETRY_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_SETTINGS_ENABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false);
- sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
+ sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true);
sDefaults.putBoolean(KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL, false);
sDefaults.putBoolean(KEY_DTMF_TYPE_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
@@ -385,11 +414,13 @@
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, "");
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, "");
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
+ sDefaults.putBoolean(KEY_CSP_ENABLED_BOOL, false);
sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null);
+ sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false);
// MMS defaults
sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
@@ -430,6 +461,9 @@
* specific SIM card. If an invalid subId is used, the returned config will contain default
* values.
*
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
* @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
* @return A {@link PersistableBundle} containing the config for the given subId, or default
* values for an invalid subId.
@@ -451,6 +485,9 @@
/**
* Gets the configuration values for the default subscription.
*
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
* @see #getConfigForSubId
*/
@Nullable
@@ -465,6 +502,8 @@
* This should be called by a carrier service app if it wants to update config at an arbitrary
* moment.
* </p>
+ * <p>Requires that the calling app has carrier privileges.
+ * @see #hasCarrierPrivileges
* <p>
* This method returns before the reload has completed, and
* {@link android.service.carrier.CarrierService#onLoadConfig} will be called from an
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 3fcd7d9..d18b86a 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2080,14 +2080,35 @@
* @hide
*/
public static boolean isVoiceMailNumber(int subId, String number) {
- String vmNumber;
+ return isVoiceMailNumber(null, subId, number);
+ }
+ /**
+ * isVoiceMailNumber: checks a given number against the voicemail
+ * number provided by the RIL and SIM card. The caller must have
+ * the READ_PHONE_STATE credential.
+ *
+ * @param context a non-null {@link Context}.
+ * @param subId the subscription id of the SIM.
+ * @param number the number to look up.
+ * @return true if the number is in the list of voicemail. False
+ * otherwise, including if the caller does not have the permission
+ * to read the VM number.
+ * @hide
+ */
+ public static boolean isVoiceMailNumber(Context context, int subId, String number) {
+ String vmNumber;
try {
- vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(subId);
+ final TelephonyManager tm;
+ if (context == null) {
+ tm = TelephonyManager.getDefault();
+ } else {
+ tm = TelephonyManager.from(context);
+ }
+ vmNumber = tm.getVoiceMailNumber(subId);
} catch (SecurityException ex) {
return false;
}
-
// Strip the separators from the number before comparing it
// to the list.
number = extractNetworkPortionAlt(number);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8291a30..ab2a98d 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;
@@ -272,6 +274,13 @@
"android.telephony.action.EMERGENCY_ASSISTANCE";
/**
+ * Open the voicemail settings activity to make changes to voicemail configuration.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CONFIGURE_VOICEMAIL =
+ "android.telephony.action.CONFIGURE_VOICEMAIL";
+
+ /**
* @hide
*/
public static final boolean EMERGENCY_ASSISTANCE_ENABLED = false;
@@ -616,15 +625,11 @@
/**
* The OMTP protocol.
- *
- * @hide
*/
public static final String VVM_TYPE_OMTP = "vvm_type_omtp";
/**
- * A flavor of OMTP protocol for Comverse.
- *
- * @hide
+ * A flavor of OMTP protocol with a different mobile originated (MO) format
*/
public static final String VVM_TYPE_CVVM = "vvm_type_cvvm";
@@ -886,16 +891,17 @@
}
/**
- * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
- * and use this only if getAllCellInfo return nulls or an empty list.
- *<p>
- * In the future this call will be deprecated.
- *<p>
+ * Returns the neighboring cell information of the device.
+ *
* @return List of NeighboringCellInfo or null if info unavailable.
*
* <p>Requires Permission:
* (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
+ *
+ * @deprecated Use (@link getAllCellInfo} which returns a superset of the information
+ * from NeighboringCellInfo.
*/
+ @Deprecated
public List<NeighboringCellInfo> getNeighboringCellInfo() {
try {
ITelephony telephony = getITelephony();
@@ -946,10 +952,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.
@@ -2143,7 +2156,7 @@
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.getMergedSubscriberIds();
+ return telephony.getMergedSubscriberIds(mContext.getOpPackageName());
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
}
@@ -3437,6 +3450,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/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index b0b95f6..2c4354b 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -143,6 +143,8 @@
public static final int OIR_DEFAULT = 0; // "user subscription default value"
public static final int OIR_PRESENTATION_RESTRICTED = 1;
public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
+ public static final int OIR_PRESENTATION_UNKNOWN = 3;
+ public static final int OIR_PRESENTATION_PAYPHONE = 4;
/**
* Values for EXTRA_DIALSTRING
@@ -373,6 +375,10 @@
return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
case PhoneConstants.PRESENTATION_ALLOWED:
return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
+ case PhoneConstants.PRESENTATION_PAYPHONE:
+ return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
+ case PhoneConstants.PRESENTATION_UNKNOWN:
+ return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
default:
return ImsCallProfile.OIR_DEFAULT;
}
@@ -389,6 +395,10 @@
return PhoneConstants.PRESENTATION_RESTRICTED;
case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
return PhoneConstants.PRESENTATION_ALLOWED;
+ case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
+ return PhoneConstants.PRESENTATION_PAYPHONE;
+ case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
+ return PhoneConstants.PRESENTATION_UNKNOWN;
default:
return PhoneConstants.PRESENTATION_UNKNOWN;
}
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..5a6bd1d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CellNetworkScanResult.java
@@ -0,0 +1,126 @@
+/*
+** 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) {
+ out.writeInt(mOperators.size());
+ 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 c253b4f..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.
*
@@ -795,7 +814,7 @@
*/
String getLine1AlphaTagForDisplay(int subId, String callingPackage);
- String[] getMergedSubscriberIds();
+ String[] getMergedSubscriberIds(String callingPackage);
/**
* Override the operator branding for the current ICCID.
@@ -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/VectorDrawableTest/res/anim/animation_favorite.xml b/tests/VectorDrawableTest/res/anim/animation_favorite.xml
index 2e2d9bb..13bd6f5 100644
--- a/tests/VectorDrawableTest/res/anim/animation_favorite.xml
+++ b/tests/VectorDrawableTest/res/anim/animation_favorite.xml
@@ -45,12 +45,6 @@
android:valueTo="#FF00FF00" />
<objectAnimator
android:duration="8000"
- android:propertyName="strokeWidth"
- android:repeatCount="-1"
- android:valueFrom="5"
- android:valueTo="20" />
- <objectAnimator
- android:duration="8000"
android:propertyName="fillColor"
android:repeatCount="-1"
android:valueFrom="#FFFF0000"
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
index 7be49a9..f93486e 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
@@ -26,6 +26,7 @@
<path
android:name="favorite"
android:fillColor="#ff000000"
+ android:strokeWidth="2"
android:pathData="M2.100006104,-6
C0.1449127197,-6,1.600006104,-5.975006104,0,-5.975006104
C-1.574996948,-5.975006104,0.00309753418,-6-1.949996948-6
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index d44afb0..610f30b 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -18,6 +18,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <ImageView android:id="@+id/full_screenshot"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
<com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -30,19 +35,29 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:background="#ffffffff"
android:elevation="8dp"
>
+ <ImageView android:id="@+id/screenshot"
+ android:layout_width="wrap_content"
+ android:layout_height="46dp"
+ android:adjustViewBounds="true" />
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ <Button android:id="@+id/do_tree"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/tree" />
+ <Button android:id="@+id/do_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/text" />
<Button android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="top|right"
- android:text="@string/start"
- />
- <ImageView android:id="@+id/screenshot"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:text="@string/start" />
</LinearLayout>
<LinearLayout android:id="@+id/bottom_content"
@@ -58,26 +73,22 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/confirm"
- />
+ android:text="@string/confirm" />
<Button android:id="@+id/complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/complete"
- />
+ android:text="@string/complete" />
<Button android:id="@+id/abort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/abort"
- />
+ android:text="@string/abort" />
</LinearLayout>
</LinearLayout>
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index 6289929..4cf4104 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,6 +17,8 @@
<resources>
<string name="start">Start</string>
+ <string name="tree">Tree</string>
+ <string name="text">Text</string>
<string name="asyncStructure">(Async structure goes here)</string>
<string name="confirm">Confirm</string>
<string name="abort">Abort</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index 8a72341..339755f 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -17,9 +17,10 @@
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.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -31,10 +32,32 @@
public class AssistVisualizer extends View {
static final String TAG = "AssistVisualizer";
+ static class TextEntry {
+ final Rect bounds;
+ final int parentLeft, parentTop;
+ final Matrix matrix;
+ final String className;
+ final CharSequence text;
+
+ TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) {
+ int left = parentLeft+node.getLeft();
+ int top = parentTop+node.getTop();
+ bounds = new Rect(left, top, left+node.getWidth(), top+node.getHeight());
+ this.parentLeft = parentLeft;
+ this.parentTop = parentTop;
+ this.matrix = new Matrix(matrix);
+ this.className = node.getClassName();
+ this.text = node.getText() != null ? node.getText() : node.getContentDescription();
+ }
+ }
+
AssistStructure mAssistStructure;
final Paint mFramePaint = new Paint();
- final ArrayList<Rect> mTextRects = new ArrayList<>();
+ final Paint mFrameNoTransformPaint = new Paint();
+ final ArrayList<Matrix> mMatrixStack = new ArrayList<>();
+ final ArrayList<TextEntry> mTextRects = new ArrayList<>();
final int[] mTmpLocation = new int[2];
+ final float[] mTmpMatrixPoint = new float[2];
public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -42,17 +65,26 @@
mFramePaint.setColor(0xffff0000);
mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0);
+ float density = getResources().getDisplayMetrics().density;
+ mFramePaint.setShadowLayer(density, density, density, 0xff000000);
+ mFrameNoTransformPaint.setColor(0xff0000ff);
+ mFrameNoTransformPaint.setStyle(Paint.Style.STROKE);
+ mFrameNoTransformPaint.setStrokeWidth(0);
+ mFrameNoTransformPaint.setShadowLayer(density, density, density, 0xff000000);
}
public void setAssistStructure(AssistStructure as) {
mAssistStructure = as;
- mAssistStructure.dump();
mTextRects.clear();
final int N = as.getWindowNodeCount();
if (N > 0) {
for (int i=0; i<N; i++) {
AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i);
- buildTextRects(windowNode.getRootViewNode(), windowNode.getLeft(),
+ mMatrixStack.clear();
+ Matrix matrix = new Matrix();
+ matrix.setTranslate(windowNode.getLeft(), windowNode.getTop());
+ mMatrixStack.add(matrix);
+ buildTextRects(windowNode.getRootViewNode(), 0, windowNode.getLeft(),
windowNode.getTop());
}
}
@@ -60,31 +92,62 @@
invalidate();
}
+ public void logTree() {
+ if (mAssistStructure != null) {
+ mAssistStructure.dump();
+ }
+ }
+
+ public void logText() {
+ final int N = mTextRects.size();
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ Log.d(TAG, "View " + te.className + " " + te.bounds.toShortString()
+ + " in " + te.parentLeft + "," + te.parentTop
+ + " matrix=" + te.matrix.toShortString() + ": "
+ + te.text);
+ }
+ }
+
public void clearAssistData() {
mAssistStructure = null;
mTextRects.clear();
}
- void buildTextRects(AssistStructure.ViewNode root, int parentLeft, int parentTop) {
+ void buildTextRects(AssistStructure.ViewNode root, int matrixStackIndex,
+ int parentLeft, int parentTop) {
if (root.getVisibility() != View.VISIBLE) {
return;
}
- int left = parentLeft+root.getLeft();
- int top = parentTop+root.getTop();
+ Matrix parentMatrix = mMatrixStack.get(matrixStackIndex);
+ matrixStackIndex++;
+ Matrix matrix;
+ if (mMatrixStack.size() > matrixStackIndex) {
+ matrix = mMatrixStack.get(matrixStackIndex);
+ matrix.set(parentMatrix);
+ } else {
+ matrix = new Matrix(parentMatrix);
+ mMatrixStack.add(matrix);
+ }
+ matrix.preTranslate(root.getLeft(), root.getTop());
+ int left = parentLeft + root.getLeft();
+ int top = parentTop + root.getTop();
+ Matrix transform = root.getTransformation();
+ if (transform != null) {
+ matrix.preConcat(transform);
+ }
if (root.getText() != null || root.getContentDescription() != null) {
- Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight());
- Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr "
- + r.toShortString() + ": "
- + (root.getText() != null ? root.getText() : root.getContentDescription()));
- mTextRects.add(r);
+ TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix);
+ mTextRects.add(te);
}
final int N = root.getChildCount();
if (N > 0) {
left -= root.getScrollX();
top -= root.getScrollY();
+ matrix.preTranslate(-root.getScrollX(), -root.getScrollY());
for (int i=0; i<N; i++) {
AssistStructure.ViewNode child = root.getChildAt(i);
- buildTextRects(child, left, top);
+ buildTextRects(child, matrixStackIndex, left, top);
}
}
}
@@ -96,9 +159,19 @@
final int N = mTextRects.size();
Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size());
for (int i=0; i<N; i++) {
- Rect r = mTextRects.get(i);
- canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1],
- r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint);
+ TextEntry te = mTextRects.get(i);
+ canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1],
+ te.bounds.right - mTmpLocation[0], te.bounds.bottom - mTmpLocation[1],
+ mFrameNoTransformPaint);
+ }
+ for (int i=0; i<N; i++) {
+ TextEntry te = mTextRects.get(i);
+ canvas.save();
+ canvas.translate(-mTmpLocation[0], -mTmpLocation[1]);
+ canvas.concat(te.matrix);
+ canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top,
+ mFramePaint);
+ canvas.restore();
}
}
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 3090a11..97c1e85 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;
@@ -42,8 +42,11 @@
View mTopContent;
View mBottomContent;
TextView mText;
+ Button mTreeButton;
+ Button mTextButton;
Button mStartButton;
ImageView mScreenshot;
+ ImageView mFullScreenshot;
Button mConfirmButton;
Button mCompleteButton;
Button mAbortButton;
@@ -110,9 +113,15 @@
mTopContent = mContentView.findViewById(R.id.top_content);
mBottomContent = mContentView.findViewById(R.id.bottom_content);
mText = (TextView)mContentView.findViewById(R.id.text);
+ mTreeButton = (Button)mContentView.findViewById(R.id.do_tree);
+ mTreeButton.setOnClickListener(this);
+ mTextButton = (Button)mContentView.findViewById(R.id.do_text);
+ mTextButton.setOnClickListener(this);
mStartButton = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this);
mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
+ mScreenshot.setOnClickListener(this);
+ mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -123,34 +132,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 +141,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) {
@@ -173,8 +165,10 @@
mScreenshot.setAdjustViewBounds(true);
mScreenshot.setMaxWidth(screenshot.getWidth()/3);
mScreenshot.setMaxHeight(screenshot.getHeight()/3);
+ mFullScreenshot.setImageBitmap(screenshot);
} else {
mScreenshot.setImageDrawable(null);
+ mFullScreenshot.setImageDrawable(null);
}
}
@@ -200,7 +194,15 @@
}
public void onClick(View v) {
- if (v == mStartButton) {
+ if (v == mTreeButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logTree();
+ }
+ } else if (v == mTextButton) {
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.logText();
+ }
+ } else if (v == mStartButton) {
mState = STATE_LAUNCHING;
updateState();
startVoiceActivity(mStartIntent);
@@ -236,9 +238,15 @@
} else if (v == mAbortButton) {
mPendingRequest.sendAbortVoiceResult(null);
mPendingRequest = null;
- } else if (v== mCompleteButton) {
+ } else if (v == mCompleteButton) {
mPendingRequest.sendCompleteVoiceResult(null);
mPendingRequest = null;
+ } else if (v == mScreenshot) {
+ if (mFullScreenshot.getVisibility() != View.VISIBLE) {
+ mFullScreenshot.setVisibility(View.VISIBLE);
+ } else {
+ mFullScreenshot.setVisibility(View.INVISIBLE);
+ }
}
updateState();
}
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/tests/WebViewTests/Android.mk b/tests/WebViewTests/Android.mk
deleted file mode 100644
index b118845..0000000
--- a/tests/WebViewTests/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := WebViewTests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/WebViewTests/AndroidManifest.xml b/tests/WebViewTests/AndroidManifest.xml
deleted file mode 100644
index 8b080c1..0000000
--- a/tests/WebViewTests/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2011 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.webviewtests">
- <application>
- <uses-library android:name="android.test.runner" />
- <activity android:name="WebViewStubActivity" android:label="WebViewStubActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.TEST" />
- </intent-filter>
- </activity>
- </application>
-
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.webviewtests"
- android:label="Tests for android.webkit.WebView" />
-</manifest>
diff --git a/tests/WebViewTests/res/layout/webview_layout.xml b/tests/WebViewTests/res/layout/webview_layout.xml
deleted file mode 100644
index d266d21..0000000
--- a/tests/WebViewTests/res/layout/webview_layout.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <WebView android:id="@+id/web_page"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-</LinearLayout>
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java
deleted file mode 100644
index c2bbdf5..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. This class tests that
- * we correctly convert JavaScript arrays to Java arrays when passing them to
- * the methods of injected Java objects.
- *
- * The conversions should follow
- * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
- * which the implementation differs from the spec are marked with
- * LIVECONNECT_COMPLIANCE.
- * FIXME: Consider making our implementation more compliant, if it will not
- * break backwards-compatibility. See b/4408210.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayCoercionTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeArrayCoercionTest extends JavaBridgeTestBase {
- private class TestObject extends Controller {
- private Object mObjectInstance;
- private CustomType mCustomTypeInstance;
-
- private boolean[] mBooleanArray;
- private byte[] mByteArray;
- private char[] mCharArray;
- private short[] mShortArray;
- private int[] mIntArray;
- private long[] mLongArray;
- private float[] mFloatArray;
- private double[] mDoubleArray;
- private String[] mStringArray;
- private Object[] mObjectArray;
- private CustomType[] mCustomTypeArray;
-
- public TestObject() {
- mObjectInstance = new Object();
- mCustomTypeInstance = new CustomType();
- }
-
- public Object getObjectInstance() {
- return mObjectInstance;
- }
- public CustomType getCustomTypeInstance() {
- return mCustomTypeInstance;
- }
-
- public synchronized void setBooleanArray(boolean[] x) {
- mBooleanArray = x;
- notifyResultIsReady();
- }
- public synchronized void setByteArray(byte[] x) {
- mByteArray = x;
- notifyResultIsReady();
- }
- public synchronized void setCharArray(char[] x) {
- mCharArray = x;
- notifyResultIsReady();
- }
- public synchronized void setShortArray(short[] x) {
- mShortArray = x;
- notifyResultIsReady();
- }
- public synchronized void setIntArray(int[] x) {
- mIntArray = x;
- notifyResultIsReady();
- }
- public synchronized void setLongArray(long[] x) {
- mLongArray = x;
- notifyResultIsReady();
- }
- public synchronized void setFloatArray(float[] x) {
- mFloatArray = x;
- notifyResultIsReady();
- }
- public synchronized void setDoubleArray(double[] x) {
- mDoubleArray = x;
- notifyResultIsReady();
- }
- public synchronized void setStringArray(String[] x) {
- mStringArray = x;
- notifyResultIsReady();
- }
- public synchronized void setObjectArray(Object[] x) {
- mObjectArray = x;
- notifyResultIsReady();
- }
- public synchronized void setCustomTypeArray(CustomType[] x) {
- mCustomTypeArray = x;
- notifyResultIsReady();
- }
-
- public synchronized boolean[] waitForBooleanArray() {
- waitForResult();
- return mBooleanArray;
- }
- public synchronized byte[] waitForByteArray() {
- waitForResult();
- return mByteArray;
- }
- public synchronized char[] waitForCharArray() {
- waitForResult();
- return mCharArray;
- }
- public synchronized short[] waitForShortArray() {
- waitForResult();
- return mShortArray;
- }
- public synchronized int[] waitForIntArray() {
- waitForResult();
- return mIntArray;
- }
- public synchronized long[] waitForLongArray() {
- waitForResult();
- return mLongArray;
- }
- public synchronized float[] waitForFloatArray() {
- waitForResult();
- return mFloatArray;
- }
- public synchronized double[] waitForDoubleArray() {
- waitForResult();
- return mDoubleArray;
- }
- public synchronized String[] waitForStringArray() {
- waitForResult();
- return mStringArray;
- }
- public synchronized Object[] waitForObjectArray() {
- waitForResult();
- return mObjectArray;
- }
- public synchronized CustomType[] waitForCustomTypeArray() {
- waitForResult();
- return mCustomTypeArray;
- }
- }
-
- // Two custom types used when testing passing objects.
- private class CustomType {
- }
-
- private TestObject mTestObject;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestObject = new TestObject();
- setUpWebView(mTestObject, "testObject");
- }
-
- // Note that all tests use a single element array for simplicity. We test
- // multiple elements elsewhere.
-
- // Test passing an array of JavaScript numbers in the int32 range to a
- // method which takes a Java array.
- public void testPassNumberInt32() throws Throwable {
- executeJavaScript("testObject.setBooleanArray([0]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
- // LIVECONNECT_COMPLIANCE: Should convert to boolean.
- executeJavaScript("testObject.setBooleanArray([42]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- executeJavaScript("testObject.setByteArray([42]);");
- assertEquals(42, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
- executeJavaScript("testObject.setCharArray([42]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([42]);");
- assertEquals(42, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([42]);");
- assertEquals(42, mTestObject.waitForIntArray()[0]);
-
- executeJavaScript("testObject.setLongArray([42]);");
- assertEquals(42L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([42]);");
- assertEquals(42.0f, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([42]);");
- assertEquals(42.0, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([42]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String.
- executeJavaScript("testObject.setStringArray([42]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([42]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript numbers in the double range to a
- // method which takes a Java array.
- public void testPassNumberDouble() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should convert to boolean.
- executeJavaScript("testObject.setBooleanArray([42.1]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- executeJavaScript("testObject.setByteArray([42.1]);");
- assertEquals(42, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
- executeJavaScript("testObject.setCharArray([42.1]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([42.1]);");
- assertEquals(42, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([42.1]);");
- assertEquals(42, mTestObject.waitForIntArray()[0]);
-
- executeJavaScript("testObject.setLongArray([42.1]);");
- assertEquals(42L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([42.1]);");
- assertEquals(42.1f, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([42.1]);");
- assertEquals(42.1, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([42.1]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String.
- executeJavaScript("testObject.setStringArray([42.1]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([42.1]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript NaN values to a method which takes a
- // Java array.
- public void testPassNumberNaN() throws Throwable {
- executeJavaScript("testObject.setBooleanArray([Number.NaN]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- executeJavaScript("testObject.setByteArray([Number.NaN]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- executeJavaScript("testObject.setCharArray([Number.NaN]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([Number.NaN]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([Number.NaN]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- executeJavaScript("testObject.setLongArray([Number.NaN]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([Number.NaN]);");
- assertEquals(Float.NaN, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([Number.NaN]);");
- assertEquals(Double.NaN, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([Number.NaN]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String.
- executeJavaScript("testObject.setStringArray([Number.NaN]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([Number.NaN]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript infinity values to a method which
- // takes a Java array.
- public void testPassNumberInfinity() throws Throwable {
- executeJavaScript("testObject.setBooleanArray([Infinity]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- executeJavaScript("testObject.setByteArray([Infinity]);");
- assertEquals(-1, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value.
- executeJavaScript("testObject.setCharArray([Infinity]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([Infinity]);");
- assertEquals(-1, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([Infinity]);");
- assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
- executeJavaScript("testObject.setLongArray([Infinity]);");
- assertEquals(-1L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([Infinity]);");
- assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([Infinity]);");
- assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([Infinity]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String.
- executeJavaScript("testObject.setStringArray([Infinity]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([Infinity]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript boolean values to a method which
- // takes a Java array.
- public void testPassBoolean() throws Throwable {
- executeJavaScript("testObject.setBooleanArray([true]);");
- assertTrue(mTestObject.waitForBooleanArray()[0]);
- executeJavaScript("testObject.setBooleanArray([false]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setByteArray([true]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
- executeJavaScript("testObject.setByteArray([false]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1.
- executeJavaScript("testObject.setCharArray([true]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
- executeJavaScript("testObject.setCharArray([false]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setShortArray([true]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
- executeJavaScript("testObject.setShortArray([false]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setIntArray([true]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
- executeJavaScript("testObject.setIntArray([false]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setLongArray([true]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
- executeJavaScript("testObject.setLongArray([false]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.0.
- executeJavaScript("testObject.setFloatArray([true]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
- executeJavaScript("testObject.setFloatArray([false]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should be 1.0.
- executeJavaScript("testObject.setDoubleArray([true]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
- executeJavaScript("testObject.setDoubleArray([false]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([true]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String.
- executeJavaScript("testObject.setStringArray([true]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([true]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript strings to a method which takes a
- // Java array.
- public void testPassString() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true.
- executeJavaScript("testObject.setBooleanArray([\"+042.10\"]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setByteArray([\"+042.10\"]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value.
- executeJavaScript("testObject.setCharArray([\"+042.10\"]);");
- assertEquals(0, mTestObject.waitForCharArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setShortArray([\"+042.10\"]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setIntArray([\"+042.10\"]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setLongArray([\"+042.10\"]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setFloatArray([\"+042.10\"]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setDoubleArray([\"+042.10\"]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number.
- executeJavaScript("testObject.setObjectArray([\"+042.10\"]);");
- assertNull(mTestObject.waitForObjectArray());
-
- executeJavaScript("testObject.setStringArray([\"+042.10\"]);");
- assertEquals("+042.10", mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([\"+042.10\"]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript objects to a method which takes a
- // Java array.
- public void testPassJavaScriptObject() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setBooleanArray([{foo: 42}]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setByteArray([{foo: 42}]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCharArray([{foo: 42}]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setShortArray([{foo: 42}]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setIntArray([{foo: 42}]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setLongArray([{foo: 42}]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setFloatArray([{foo: 42}]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setDoubleArray([{foo: 42}]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setObjectArray([{foo: 42}]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should call toString() on object.
- executeJavaScript("testObject.setStringArray([{foo: 42}]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeArray([{foo: 42}]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of Java objects to a method which takes a Java
- // array.
- public void testPassJavaObject() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setBooleanArray([testObject.getObjectInstance()]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setByteArray([testObject.getObjectInstance()]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCharArray([testObject.getObjectInstance()]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setShortArray([testObject.getObjectInstance()]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setIntArray([testObject.getObjectInstance()]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setLongArray([testObject.getObjectInstance()]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setFloatArray([testObject.getObjectInstance()]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setDoubleArray([testObject.getObjectInstance()]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create an array and pass Java object.
- executeJavaScript("testObject.setObjectArray([testObject.getObjectInstance()]);");
- assertNull(mTestObject.waitForObjectArray());
-
- // LIVECONNECT_COMPLIANCE: Should call toString() on object.
- executeJavaScript("testObject.setStringArray([testObject.getObjectInstance()]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and pass Java object.
- executeJavaScript("testObject.setCustomTypeArray([testObject.getObjectInstance()]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- executeJavaScript("testObject.setCustomTypeArray([testObject.getCustomTypeInstance()]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript null values to a method which takes
- // a Java array.
- public void testPassNull() throws Throwable {
- executeJavaScript("testObject.setByteArray([null]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- executeJavaScript("testObject.setCharArray([null]);");
- assertEquals('\u0000', mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([null]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([null]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- executeJavaScript("testObject.setLongArray([null]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([null]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([null]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- executeJavaScript("testObject.setBooleanArray([null]);");
- assertFalse(mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and pass null.
- executeJavaScript("testObject.setObjectArray([null]);");
- assertNull(mTestObject.waitForObjectArray());
-
- executeJavaScript("testObject.setStringArray([null]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and pass null.
- executeJavaScript("testObject.setCustomTypeArray([null]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-
- // Test passing an array of JavaScript undefined values to a method which
- // takes a Java array.
- public void testPassUndefined() throws Throwable {
- executeJavaScript("testObject.setByteArray([undefined]);");
- assertEquals(0, mTestObject.waitForByteArray()[0]);
-
- executeJavaScript("testObject.setCharArray([undefined]);");
- assertEquals(0, mTestObject.waitForCharArray()[0]);
-
- executeJavaScript("testObject.setShortArray([undefined]);");
- assertEquals(0, mTestObject.waitForShortArray()[0]);
-
- executeJavaScript("testObject.setIntArray([undefined]);");
- assertEquals(0, mTestObject.waitForIntArray()[0]);
-
- executeJavaScript("testObject.setLongArray([undefined]);");
- assertEquals(0L, mTestObject.waitForLongArray()[0]);
-
- executeJavaScript("testObject.setFloatArray([undefined]);");
- assertEquals(0.0f, mTestObject.waitForFloatArray()[0]);
-
- executeJavaScript("testObject.setDoubleArray([undefined]);");
- assertEquals(0.0, mTestObject.waitForDoubleArray()[0]);
-
- executeJavaScript("testObject.setBooleanArray([undefined]);");
- assertEquals(false, mTestObject.waitForBooleanArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and pass null.
- executeJavaScript("testObject.setObjectArray([undefined]);");
- assertNull(mTestObject.waitForObjectArray());
-
- executeJavaScript("testObject.setStringArray([undefined]);");
- assertNull(mTestObject.waitForStringArray()[0]);
-
- // LIVECONNECT_COMPLIANCE: Should create array and pass null.
- executeJavaScript("testObject.setCustomTypeArray([undefined]);");
- assertNull(mTestObject.waitForCustomTypeArray());
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java
deleted file mode 100644
index 2fd42a74d..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. This class tests the
- * general use of arrays.
- *
- * The conversions should follow
- * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
- * which the implementation differs from the spec are marked with
- * LIVECONNECT_COMPLIANCE.
- * FIXME: Consider making our implementation more compliant, if it will not
- * break backwards-compatibility. See b/4408210.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeArrayTest extends JavaBridgeTestBase {
- private class TestObject extends Controller {
- private boolean mBooleanValue;
- private int mIntValue;
- private String mStringValue;
-
- private int[] mIntArray;
- private int[][] mIntIntArray;
-
- private boolean mWasArrayMethodCalled;
-
- public synchronized void setBooleanValue(boolean x) {
- mBooleanValue = x;
- notifyResultIsReady();
- }
- public synchronized void setIntValue(int x) {
- mIntValue = x;
- notifyResultIsReady();
- }
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
-
- public synchronized boolean waitForBooleanValue() {
- waitForResult();
- return mBooleanValue;
- }
- public synchronized int waitForIntValue() {
- waitForResult();
- return mIntValue;
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
-
- public synchronized void setIntArray(int[] x) {
- mIntArray = x;
- notifyResultIsReady();
- }
- public synchronized void setIntIntArray(int[][] x) {
- mIntIntArray = x;
- notifyResultIsReady();
- }
-
- public synchronized int[] waitForIntArray() {
- waitForResult();
- return mIntArray;
- }
- public synchronized int[][] waitForIntIntArray() {
- waitForResult();
- return mIntIntArray;
- }
-
- public synchronized int[] arrayMethod() {
- mWasArrayMethodCalled = true;
- return new int[] {42, 43, 44};
- }
-
- public synchronized boolean wasArrayMethodCalled() {
- return mWasArrayMethodCalled;
- }
- }
-
- private TestObject mTestObject;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestObject = new TestObject();
- setUpWebView(mTestObject, "testObject");
- }
-
- public void testArrayLength() throws Throwable {
- executeJavaScript("testObject.setIntArray([42, 43, 44]);");
- int[] result = mTestObject.waitForIntArray();
- assertEquals(3, result.length);
- assertEquals(42, result[0]);
- assertEquals(43, result[1]);
- assertEquals(44, result[2]);
- }
-
- public void testPassNull() throws Throwable {
- executeJavaScript("testObject.setIntArray(null);");
- assertNull(mTestObject.waitForIntArray());
- }
-
- public void testPassUndefined() throws Throwable {
- executeJavaScript("testObject.setIntArray(undefined);");
- assertNull(mTestObject.waitForIntArray());
- }
-
- public void testPassEmptyArray() throws Throwable {
- executeJavaScript("testObject.setIntArray([]);");
- assertEquals(0, mTestObject.waitForIntArray().length);
- }
-
- // Note that this requires being able to pass a string from JavaScript to
- // Java.
- public void testPassArrayToStringMethod() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should call toString() on array.
- executeJavaScript("testObject.setStringValue([42, 42, 42]);");
- assertEquals("undefined", mTestObject.waitForStringValue());
- }
-
- // Note that this requires being able to pass an integer from JavaScript to
- // Java.
- public void testPassArrayToNonStringNonArrayMethod() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception.
- executeJavaScript("testObject.setIntValue([42, 42, 42]);");
- assertEquals(0, mTestObject.waitForIntValue());
- }
-
- public void testPassNonArrayToArrayMethod() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception.
- executeJavaScript("testObject.setIntArray(42);");
- assertNull(mTestObject.waitForIntArray());
- }
-
- public void testObjectWithLengthProperty() throws Throwable {
- executeJavaScript("testObject.setIntArray({length: 3, 1: 42});");
- int[] result = mTestObject.waitForIntArray();
- assertEquals(3, result.length);
- assertEquals(0, result[0]);
- assertEquals(42, result[1]);
- assertEquals(0, result[2]);
- }
-
- public void testNonNumericLengthProperty() throws Throwable {
- // LIVECONNECT_COMPLIANCE: This should not count as an array, so we
- // should raise a JavaScript exception.
- executeJavaScript("testObject.setIntArray({length: \"foo\"});");
- assertNull(mTestObject.waitForIntArray());
- }
-
- public void testLengthOutOfBounds() throws Throwable {
- // LIVECONNECT_COMPLIANCE: This should not count as an array, so we
- // should raise a JavaScript exception.
- executeJavaScript("testObject.setIntArray({length: -1});");
- assertNull(mTestObject.waitForIntArray());
-
- // LIVECONNECT_COMPLIANCE: This should not count as an array, so we
- // should raise a JavaScript exception.
- long length = (long)Integer.MAX_VALUE + 1L;
- executeJavaScript("testObject.setIntArray({length: " + length + "});");
- assertNull(mTestObject.waitForIntArray());
-
- // LIVECONNECT_COMPLIANCE: This should not count as an array, so we
- // should raise a JavaScript exception.
- length = (long)Integer.MAX_VALUE + 1L - (long)Integer.MIN_VALUE + 1L;
- executeJavaScript("testObject.setIntArray({length: " + length + "});");
- assertNull(mTestObject.waitForIntArray());
- }
-
- public void testSparseArray() throws Throwable {
- executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);");
- int[] result = mTestObject.waitForIntArray();
- assertEquals(4, result.length);
- assertEquals(42, result[0]);
- assertEquals(43, result[1]);
- assertEquals(0, result[2]);
- assertEquals(45, result[3]);
- }
-
- // Note that this requires being able to pass a boolean from JavaScript to
- // Java.
- public void testMethodReturningArrayNotCalled() throws Throwable {
- // We don't invoke methods which return arrays, but note that no
- // exception is raised.
- // LIVECONNECT_COMPLIANCE: Should call method and convert result to
- // JavaScript array.
- executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())");
- assertTrue(mTestObject.waitForBooleanValue());
- assertFalse(mTestObject.wasArrayMethodCalled());
- }
-
- public void testMultiDimensionalArrayMethod() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays.
- executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);");
- assertNull(mTestObject.waitForIntIntArray());
- }
-
- public void testPassMultiDimensionalArray() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays.
- executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);");
- int[] result = mTestObject.waitForIntArray();
- assertEquals(2, result.length);
- assertEquals(0, result[0]);
- assertEquals(0, result[1]);
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java
deleted file mode 100644
index 1ecccf6..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. Tests a number of features including ...
- * - The type of injected objects
- * - The type of their methods
- * - Replacing objects
- * - Removing objects
- * - Access control
- * - Calling methods on returned objects
- * - Multiply injected objects
- * - Threading
- * - Inheritance
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeBasicsTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeBasicsTest extends JavaBridgeTestBase {
- private class TestController extends Controller {
- private int mIntValue;
- private long mLongValue;
- private String mStringValue;
- private boolean mBooleanValue;
-
- public synchronized void setIntValue(int x) {
- mIntValue = x;
- notifyResultIsReady();
- }
- public synchronized void setLongValue(long x) {
- mLongValue = x;
- notifyResultIsReady();
- }
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
- public synchronized void setBooleanValue(boolean x) {
- mBooleanValue = x;
- notifyResultIsReady();
- }
-
- public synchronized int waitForIntValue() {
- waitForResult();
- return mIntValue;
- }
- public synchronized long waitForLongValue() {
- waitForResult();
- return mLongValue;
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
- public synchronized boolean waitForBooleanValue() {
- waitForResult();
- return mBooleanValue;
- }
- }
-
- private static class ObjectWithStaticMethod {
- public static String staticMethod() {
- return "foo";
- }
- }
-
- TestController mTestController;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestController = new TestController();
- setUpWebView(mTestController, "testController");
- }
-
- // Note that this requires that we can pass a JavaScript string to Java.
- protected String executeJavaScriptAndGetStringResult(String script) throws Throwable {
- executeJavaScript("testController.setStringValue(" + script + ");");
- return mTestController.waitForStringValue();
- }
-
- protected void injectObjectAndReload(final Object object, final String name) throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().addJavascriptInterface(object, name);
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- }
-
- // Note that this requires that we can pass a JavaScript boolean to Java.
- private void assertRaisesException(String script) throws Throwable {
- executeJavaScript("try {" +
- script + ";" +
- " testController.setBooleanValue(false);" +
- "} catch (exception) {" +
- " testController.setBooleanValue(true);" +
- "}");
- assertTrue(mTestController.waitForBooleanValue());
- }
-
- public void testTypeOfInjectedObject() throws Throwable {
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController"));
- }
-
- public void testAdditionNotReflectedUntilReload() throws Throwable {
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject"));
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().addJavascriptInterface(new Object(), "testObject");
- }
- });
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject"));
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
- }
-
- public void testRemovalNotReflectedUntilReload() throws Throwable {
- injectObjectAndReload(new Object(), "testObject");
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().removeJavascriptInterface("testObject");
- }
- });
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject"));
- }
-
- public void testRemoveObjectNotAdded() throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().removeJavascriptInterface("foo");
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof foo"));
- }
-
- public void testTypeOfMethod() throws Throwable {
- assertEquals("function",
- executeJavaScriptAndGetStringResult("typeof testController.setStringValue"));
- }
-
- public void testTypeOfInvalidMethod() throws Throwable {
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testController.foo"));
- }
-
- public void testCallingInvalidMethodRaisesException() throws Throwable {
- assertRaisesException("testController.foo()");
- }
-
- public void testUncaughtJavaExceptionRaisesJavaException() throws Throwable {
- injectObjectAndReload(new Object() {
- public void method() { throw new RuntimeException("foo"); }
- }, "testObject");
- assertRaisesException("testObject.method()");
- }
-
- // Note that this requires that we can pass a JavaScript string to Java.
- public void testTypeOfStaticMethod() throws Throwable {
- injectObjectAndReload(new ObjectWithStaticMethod(), "testObject");
- executeJavaScript("testController.setStringValue(typeof testObject.staticMethod)");
- assertEquals("function", mTestController.waitForStringValue());
- }
-
- // Note that this requires that we can pass a JavaScript string to Java.
- public void testCallStaticMethod() throws Throwable {
- injectObjectAndReload(new ObjectWithStaticMethod(), "testObject");
- executeJavaScript("testController.setStringValue(testObject.staticMethod())");
- assertEquals("foo", mTestController.waitForStringValue());
- }
-
- public void testPrivateMethodNotExposed() throws Throwable {
- injectObjectAndReload(new Object() {
- private void method() {}
- }, "testObject");
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.method"));
- }
-
- public void testReplaceInjectedObject() throws Throwable {
- injectObjectAndReload(new Object() {
- public void method() { mTestController.setStringValue("object 1"); }
- }, "testObject");
- executeJavaScript("testObject.method()");
- assertEquals("object 1", mTestController.waitForStringValue());
-
- injectObjectAndReload(new Object() {
- public void method() { mTestController.setStringValue("object 2"); }
- }, "testObject");
- executeJavaScript("testObject.method()");
- assertEquals("object 2", mTestController.waitForStringValue());
- }
-
- public void testInjectNullObjectIsIgnored() throws Throwable {
- injectObjectAndReload(null, "testObject");
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject"));
- }
-
- public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwable {
- injectObjectAndReload(new Object(), "testObject");
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
- injectObjectAndReload(null, "testObject");
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
- }
-
- public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable {
- injectObjectAndReload(new Object() {
- public void method() { mTestController.setStringValue("0 args"); }
- public void method(int x) { mTestController.setStringValue("1 arg"); }
- public void method(int x, int y) { mTestController.setStringValue("2 args"); }
- }, "testObject");
- executeJavaScript("testObject.method()");
- assertEquals("0 args", mTestController.waitForStringValue());
- executeJavaScript("testObject.method(42)");
- assertEquals("1 arg", mTestController.waitForStringValue());
- executeJavaScript("testObject.method(null)");
- assertEquals("1 arg", mTestController.waitForStringValue());
- executeJavaScript("testObject.method(undefined)");
- assertEquals("1 arg", mTestController.waitForStringValue());
- executeJavaScript("testObject.method(42, 42)");
- assertEquals("2 args", mTestController.waitForStringValue());
- }
-
- public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable {
- assertRaisesException("testController.setIntValue()");
- assertRaisesException("testController.setIntValue(42, 42)");
- }
-
- public void testObjectPersistsAcrossPageLoads() throws Throwable {
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController"));
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController"));
- }
-
- public void testSameObjectInjectedMultipleTimes() throws Throwable {
- class TestObject {
- private int mNumMethodInvocations;
- public void method() { mTestController.setIntValue(++mNumMethodInvocations); }
- }
- final TestObject testObject = new TestObject();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().addJavascriptInterface(testObject, "testObject1");
- getWebView().addJavascriptInterface(testObject, "testObject2");
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- executeJavaScript("testObject1.method()");
- assertEquals(1, mTestController.waitForIntValue());
- executeJavaScript("testObject2.method()");
- assertEquals(2, mTestController.waitForIntValue());
- }
-
- public void testCallMethodOnReturnedObject() throws Throwable {
- injectObjectAndReload(new Object() {
- public Object getInnerObject() {
- return new Object() {
- public void method(int x) { mTestController.setIntValue(x); }
- };
- }
- }, "testObject");
- executeJavaScript("testObject.getInnerObject().method(42)");
- assertEquals(42, mTestController.waitForIntValue());
- }
-
- public void testReturnedObjectInjectedElsewhere() throws Throwable {
- class InnerObject {
- private int mNumMethodInvocations;
- public void method() { mTestController.setIntValue(++mNumMethodInvocations); }
- }
- final InnerObject innerObject = new InnerObject();
- final Object object = new Object() {
- public InnerObject getInnerObject() {
- return innerObject;
- }
- };
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- getWebView().addJavascriptInterface(object, "testObject");
- getWebView().addJavascriptInterface(innerObject, "innerObject");
- getWebView().reload();
- }
- });
- mWebViewClient.waitForOnPageFinished();
- executeJavaScript("testObject.getInnerObject().method()");
- assertEquals(1, mTestController.waitForIntValue());
- executeJavaScript("innerObject.method()");
- assertEquals(2, mTestController.waitForIntValue());
- }
-
- public void testMethodInvokedOnBackgroundThread() throws Throwable {
- injectObjectAndReload(new Object() {
- public void captureThreadId() {
- mTestController.setLongValue(Thread.currentThread().getId());
- }
- }, "testObject");
- executeJavaScript("testObject.captureThreadId()");
- final long threadId = mTestController.waitForLongValue();
- assertFalse(threadId == Thread.currentThread().getId());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertFalse(threadId == Thread.currentThread().getId());
- }
- });
- }
-
- public void testPublicInheritedMethod() throws Throwable {
- class Base {
- public void method(int x) { mTestController.setIntValue(x); }
- }
- class Derived extends Base {
- }
- injectObjectAndReload(new Derived(), "testObject");
- assertEquals("function", executeJavaScriptAndGetStringResult("typeof testObject.method"));
- executeJavaScript("testObject.method(42)");
- assertEquals(42, mTestController.waitForIntValue());
- }
-
- public void testPrivateInheritedMethod() throws Throwable {
- class Base {
- private void method() {}
- }
- class Derived extends Base {
- }
- injectObjectAndReload(new Derived(), "testObject");
- assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.method"));
- }
-
- public void testOverriddenMethod() throws Throwable {
- class Base {
- public void method() { mTestController.setStringValue("base"); }
- }
- class Derived extends Base {
- public void method() { mTestController.setStringValue("derived"); }
- }
- injectObjectAndReload(new Derived(), "testObject");
- executeJavaScript("testObject.method()");
- assertEquals("derived", mTestController.waitForStringValue());
- }
-
- public void testEnumerateMembers() throws Throwable {
- injectObjectAndReload(new Object() {
- public void method() {}
- private void privateMethod() {}
- public int field;
- private int privateField;
- }, "testObject");
- executeJavaScript(
- "var result = \"\"; " +
- "for (x in testObject) { result += \" \" + x } " +
- "testController.setStringValue(result);");
- // LIVECONNECT_COMPLIANCE: Should be able to enumerate members.
- assertEquals("", mTestController.waitForStringValue());
- }
-
- public void testReflectPublicMethod() throws Throwable {
- injectObjectAndReload(new Object() {
- public String method() { return "foo"; }
- }, "testObject");
- assertEquals("foo", executeJavaScriptAndGetStringResult(
- "testObject.getClass().getMethod('method', null).invoke(testObject, null)" +
- ".toString()"));
- }
-
- public void testReflectPublicField() throws Throwable {
- injectObjectAndReload(new Object() {
- public String field = "foo";
- }, "testObject");
- assertEquals("foo", executeJavaScriptAndGetStringResult(
- "testObject.getClass().getField('field').get(testObject).toString()"));
- }
-
- public void testReflectPrivateMethodRaisesException() throws Throwable {
- injectObjectAndReload(new Object() {
- private void method() {};
- }, "testObject");
- assertRaisesException("testObject.getClass().getMethod('method', null)");
- // getDeclaredMethod() is able to access a private method, but invoke()
- // throws a Java exception.
- assertRaisesException(
- "testObject.getClass().getDeclaredMethod('method', null).invoke(testObject, null)");
- }
-
- public void testReflectPrivateFieldRaisesException() throws Throwable {
- injectObjectAndReload(new Object() {
- private int field;
- }, "testObject");
- assertRaisesException("testObject.getClass().getField('field')");
- // getDeclaredField() is able to access a private field, but getInt()
- // throws a Java exception.
- assertRaisesException(
- "testObject.getClass().getDeclaredField('field').getInt(testObject)");
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java
deleted file mode 100644
index 3f0e2b3..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge.
- *
- * Ensures that injected objects are exposed to child frames as well as the
- * main frame.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeChildFrameTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
- private class TestController extends Controller {
- private String mStringValue;
-
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
- }
-
- TestController mTestController;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestController = new TestController();
- setUpWebView(mTestController, "testController");
- }
-
- public void testInjectedObjectPresentInChildFrame() throws Throwable {
- // In the case that the test fails (i.e. the child frame doesn't get the injected object,
- // the call to testController.setStringValue in the child frame's onload handler will
- // not be made.
- getActivity().getWebView().loadData(
- "<html><head></head><body>" +
- "<iframe id=\"childFrame\" onload=\"testController.setStringValue('PASS');\" />" +
- "</body></html>", "text/html", null);
- assertEquals("PASS", mTestController.waitForStringValue());
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java
deleted file mode 100644
index a0f78a4..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. This class tests that
- * we correctly convert JavaScript values to Java values when passing them to
- * the methods of injected Java objects.
- *
- * The conversions should follow
- * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
- * which the implementation differs from the spec are marked with
- * LIVECONNECT_COMPLIANCE.
- * FIXME: Consider making our implementation more compliant, if it will not
- * break backwards-compatibility. See b/4408210.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeCoercionTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeCoercionTest extends JavaBridgeTestBase {
- private class TestObject extends Controller {
- private Object objectInstance;
- private CustomType customTypeInstance;
- private CustomType2 customType2Instance;
-
- private boolean mBooleanValue;
- private byte mByteValue;
- private char mCharValue;
- private short mShortValue;
- private int mIntValue;
- private long mLongValue;
- private float mFloatValue;
- private double mDoubleValue;
- private String mStringValue;
- private Object mObjectValue;
- private CustomType mCustomTypeValue;
-
- public TestObject() {
- objectInstance = new Object();
- customTypeInstance = new CustomType();
- customType2Instance = new CustomType2();
- }
-
- public Object getObjectInstance() {
- return objectInstance;
- }
- public CustomType getCustomTypeInstance() {
- return customTypeInstance;
- }
- public CustomType2 getCustomType2Instance() {
- return customType2Instance;
- }
-
- public synchronized void setBooleanValue(boolean x) {
- mBooleanValue = x;
- notifyResultIsReady();
- }
- public synchronized void setByteValue(byte x) {
- mByteValue = x;
- notifyResultIsReady();
- }
- public synchronized void setCharValue(char x) {
- mCharValue = x;
- notifyResultIsReady();
- }
- public synchronized void setShortValue(short x) {
- mShortValue = x;
- notifyResultIsReady();
- }
- public synchronized void setIntValue(int x) {
- mIntValue = x;
- notifyResultIsReady();
- }
- public synchronized void setLongValue(long x) {
- mLongValue = x;
- notifyResultIsReady();
- }
- public synchronized void setFloatValue(float x) {
- mFloatValue = x;
- notifyResultIsReady();
- }
- public synchronized void setDoubleValue(double x) {
- mDoubleValue = x;
- notifyResultIsReady();
- }
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
- public synchronized void setObjectValue(Object x) {
- mObjectValue = x;
- notifyResultIsReady();
- }
- public synchronized void setCustomTypeValue(CustomType x) {
- mCustomTypeValue = x;
- notifyResultIsReady();
- }
-
- public synchronized boolean waitForBooleanValue() {
- waitForResult();
- return mBooleanValue;
- }
- public synchronized byte waitForByteValue() {
- waitForResult();
- return mByteValue;
- }
- public synchronized char waitForCharValue() {
- waitForResult();
- return mCharValue;
- }
- public synchronized short waitForShortValue() {
- waitForResult();
- return mShortValue;
- }
- public synchronized int waitForIntValue() {
- waitForResult();
- return mIntValue;
- }
- public synchronized long waitForLongValue() {
- waitForResult();
- return mLongValue;
- }
- public synchronized float waitForFloatValue() {
- waitForResult();
- return mFloatValue;
- }
- public synchronized double waitForDoubleValue() {
- waitForResult();
- return mDoubleValue;
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
- public synchronized Object waitForObjectValue() {
- waitForResult();
- return mObjectValue;
- }
- public synchronized CustomType waitForCustomTypeValue() {
- waitForResult();
- return mCustomTypeValue;
- }
- }
-
- // Two custom types used when testing passing objects.
- private static class CustomType {
- }
- private static class CustomType2 {
- }
-
- private TestObject mTestObject;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestObject = new TestObject();
- setUpWebView(mTestObject, "testObject");
- }
-
- // Test passing a JavaScript number in the int32 range to a method of an
- // injected object.
- public void testPassNumberInt32() throws Throwable {
- executeJavaScript("testObject.setByteValue(42);");
- assertEquals(42, mTestObject.waitForByteValue());
- executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);");
- assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
- executeJavaScript("testObject.setCharValue(42);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(42);");
- assertEquals(42, mTestObject.waitForShortValue());
- executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42);");
- assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(42);");
- assertEquals(42, mTestObject.waitForIntValue());
-
- executeJavaScript("testObject.setLongValue(42);");
- assertEquals(42L, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(42);");
- assertEquals(42.0f, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(42);");
- assertEquals(42.0, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
- executeJavaScript("testObject.setObjectValue(42);");
- assertNull(mTestObject.waitForObjectValue());
-
- // The spec allows the JS engine flexibility in how to format the number.
- executeJavaScript("testObject.setStringValue(42);");
- String str = mTestObject.waitForStringValue();
- assertTrue("42".equals(str) || "42.0".equals(str));
-
- executeJavaScript("testObject.setBooleanValue(0);");
- assertFalse(mTestObject.waitForBooleanValue());
- // LIVECONNECT_COMPLIANCE: Should be true;
- executeJavaScript("testObject.setBooleanValue(42);");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(42);");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing a JavaScript number in the double range to a method of an
- // injected object.
- public void testPassNumberDouble() throws Throwable {
- executeJavaScript("testObject.setByteValue(42.1);");
- assertEquals(42, mTestObject.waitForByteValue());
- executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);");
- assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue());
- executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);");
- assertEquals(-1, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value.
- executeJavaScript("testObject.setCharValue(42.1);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(42.1);");
- assertEquals(42, mTestObject.waitForShortValue());
- executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);");
- assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue());
- executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);");
- assertEquals(-1, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(42.1);");
- assertEquals(42, mTestObject.waitForIntValue());
- executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);");
- assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
-
- executeJavaScript("testObject.setLongValue(42.1);");
- assertEquals(42L, mTestObject.waitForLongValue());
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
- executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);");
- assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(42.1);");
- assertEquals(42.1f, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(42.1);");
- assertEquals(42.1, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
- executeJavaScript("testObject.setObjectValue(42.1);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setStringValue(42.1);");
- assertEquals("42.1", mTestObject.waitForStringValue());
-
- executeJavaScript("testObject.setBooleanValue(0.0);");
- assertFalse(mTestObject.waitForBooleanValue());
- // LIVECONNECT_COMPLIANCE: Should be true.
- executeJavaScript("testObject.setBooleanValue(42.1);");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(42.1);");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing JavaScript NaN to a method of an injected object.
- public void testPassNumberNaN() throws Throwable {
- executeJavaScript("testObject.setByteValue(Number.NaN);");
- assertEquals(0, mTestObject.waitForByteValue());
-
- executeJavaScript("testObject.setCharValue(Number.NaN);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(Number.NaN);");
- assertEquals(0, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(Number.NaN);");
- assertEquals(0, mTestObject.waitForIntValue());
-
- executeJavaScript("testObject.setLongValue(Number.NaN);");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(Number.NaN);");
- assertEquals(Float.NaN, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(Number.NaN);");
- assertEquals(Double.NaN, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
- executeJavaScript("testObject.setObjectValue(Number.NaN);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setStringValue(Number.NaN);");
- assertEquals("NaN", mTestObject.waitForStringValue());
-
- executeJavaScript("testObject.setBooleanValue(Number.NaN);");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(Number.NaN);");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing JavaScript infinity to a method of an injected object.
- public void testPassNumberInfinity() throws Throwable {
- executeJavaScript("testObject.setByteValue(Infinity);");
- assertEquals(-1, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value.
- executeJavaScript("testObject.setCharValue(Infinity);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(Infinity);");
- assertEquals(-1, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(Infinity);");
- assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue());
-
- // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE.
- executeJavaScript("testObject.setLongValue(Infinity);");
- assertEquals(-1L, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(Infinity);");
- assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(Infinity);");
- assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number.
- executeJavaScript("testObject.setObjectValue(Infinity);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setStringValue(Infinity);");
- assertEquals("Inf", mTestObject.waitForStringValue());
-
- executeJavaScript("testObject.setBooleanValue(Infinity);");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(Infinity);");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing a JavaScript boolean to a method of an injected object.
- public void testPassBoolean() throws Throwable {
- executeJavaScript("testObject.setBooleanValue(true);");
- assertTrue(mTestObject.waitForBooleanValue());
- executeJavaScript("testObject.setBooleanValue(false);");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Boolean.
- executeJavaScript("testObject.setObjectValue(true);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setStringValue(false);");
- assertEquals("false", mTestObject.waitForStringValue());
- executeJavaScript("testObject.setStringValue(true);");
- assertEquals("true", mTestObject.waitForStringValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setByteValue(true);");
- assertEquals(0, mTestObject.waitForByteValue());
- executeJavaScript("testObject.setByteValue(false);");
- assertEquals(0, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1.
- executeJavaScript("testObject.setCharValue(true);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
- executeJavaScript("testObject.setCharValue(false);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setShortValue(true);");
- assertEquals(0, mTestObject.waitForShortValue());
- executeJavaScript("testObject.setShortValue(false);");
- assertEquals(0, mTestObject.waitForShortValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setIntValue(true);");
- assertEquals(0, mTestObject.waitForIntValue());
- executeJavaScript("testObject.setIntValue(false);");
- assertEquals(0, mTestObject.waitForIntValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.
- executeJavaScript("testObject.setLongValue(true);");
- assertEquals(0L, mTestObject.waitForLongValue());
- executeJavaScript("testObject.setLongValue(false);");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.0.
- executeJavaScript("testObject.setFloatValue(true);");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
- executeJavaScript("testObject.setFloatValue(false);");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- // LIVECONNECT_COMPLIANCE: Should be 1.0.
- executeJavaScript("testObject.setDoubleValue(true);");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
- executeJavaScript("testObject.setDoubleValue(false);");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(true);");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing a JavaScript string to a method of an injected object.
- public void testPassString() throws Throwable {
- executeJavaScript("testObject.setStringValue(\"+042.10\");");
- assertEquals("+042.10", mTestObject.waitForStringValue());
-
- // Make sure that we distinguish between the empty string and NULL.
- executeJavaScript("testObject.setStringValue(\"\");");
- assertEquals("", mTestObject.waitForStringValue());
-
- // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.String.
- executeJavaScript("testObject.setObjectValue(\"+042.10\");");
- assertNull(mTestObject.waitForObjectValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setByteValue(\"+042.10\");");
- assertEquals(0, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setShortValue(\"+042.10\");");
- assertEquals(0, mTestObject.waitForShortValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setIntValue(\"+042.10\");");
- assertEquals(0, mTestObject.waitForIntValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setLongValue(\"+042.10\");");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setFloatValue(\"+042.10\");");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type.
- executeJavaScript("testObject.setDoubleValue(\"+042.10\");");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value.
- executeJavaScript("testObject.setCharValue(\"+042.10\");");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true.
- executeJavaScript("testObject.setBooleanValue(\"+042.10\");");
- assertFalse(mTestObject.waitForBooleanValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");");
- assertNull(mTestObject.waitForCustomTypeValue());
- }
-
- // Test passing a JavaScript object to a method of an injected object.
- public void testPassJavaScriptObject() throws Throwable {
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setObjectValue({foo: 42});");
- assertNull(mTestObject.waitForObjectValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCustomTypeValue({foo: 42});");
- assertNull(mTestObject.waitForCustomTypeValue());
-
- // LIVECONNECT_COMPLIANCE: Should call toString() on object.
- executeJavaScript("testObject.setStringValue({foo: 42});");
- assertEquals("undefined", mTestObject.waitForStringValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setByteValue({foo: 42});");
- assertEquals(0, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCharValue({foo: 42});");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setShortValue({foo: 42});");
- assertEquals(0, mTestObject.waitForShortValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setIntValue({foo: 42});");
- assertEquals(0, mTestObject.waitForIntValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setLongValue({foo: 42});");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setFloatValue({foo: 42});");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setDoubleValue({foo: 42});");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setBooleanValue({foo: 42});");
- assertFalse(mTestObject.waitForBooleanValue());
- }
-
- // Test passing a Java object to a method of an injected object. Note that
- // this test requires being able to return objects from the methods of
- // injected objects. This is tested elsewhere.
- public void testPassJavaObject() throws Throwable {
- executeJavaScript("testObject.setObjectValue(testObject.getObjectInstance());");
- assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue());
- executeJavaScript("testObject.setObjectValue(testObject.getCustomTypeInstance());");
- assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setCustomTypeValue(testObject.getObjectInstance());");
- assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForCustomTypeValue());
- executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomTypeInstance());");
- assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue());
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception, as the types are unrelated.
- executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomType2Instance());");
- assertTrue(mTestObject.getCustomType2Instance() ==
- (Object)mTestObject.waitForCustomTypeValue());
-
- // LIVECONNECT_COMPLIANCE: Should call toString() on object.
- executeJavaScript("testObject.setStringValue(testObject.getObjectInstance());");
- assertEquals("undefined", mTestObject.waitForStringValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setByteValue(testObject.getObjectInstance());");
- assertEquals(0, mTestObject.waitForByteValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setCharValue(testObject.getObjectInstance());");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setShortValue(testObject.getObjectInstance());");
- assertEquals(0, mTestObject.waitForShortValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setIntValue(testObject.getObjectInstance());");
- assertEquals(0, mTestObject.waitForIntValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setLongValue(testObject.getObjectInstance());");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setFloatValue(testObject.getObjectInstance());");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setDoubleValue(testObject.getObjectInstance());");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception.
- executeJavaScript("testObject.setBooleanValue(testObject.getObjectInstance());");
- assertFalse(mTestObject.waitForBooleanValue());
- }
-
- // Test passing JavaScript null to a method of an injected object.
- public void testPassNull() throws Throwable {
- executeJavaScript("testObject.setObjectValue(null);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setCustomTypeValue(null);");
- assertNull(mTestObject.waitForCustomTypeValue());
-
- executeJavaScript("testObject.setStringValue(null);");
- assertNull(mTestObject.waitForStringValue());
-
- executeJavaScript("testObject.setByteValue(null);");
- assertEquals(0, mTestObject.waitForByteValue());
-
- executeJavaScript("testObject.setCharValue(null);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(null);");
- assertEquals(0, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(null);");
- assertEquals(0, mTestObject.waitForIntValue());
-
- executeJavaScript("testObject.setLongValue(null);");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(null);");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(null);");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- executeJavaScript("testObject.setBooleanValue(null);");
- assertFalse(mTestObject.waitForBooleanValue());
- }
-
- // Test passing JavaScript undefined to a method of an injected object.
- public void testPassUndefined() throws Throwable {
- executeJavaScript("testObject.setObjectValue(undefined);");
- assertNull(mTestObject.waitForObjectValue());
-
- executeJavaScript("testObject.setCustomTypeValue(undefined);");
- assertNull(mTestObject.waitForCustomTypeValue());
-
- // LIVECONNECT_COMPLIANCE: Should be NULL.
- executeJavaScript("testObject.setStringValue(undefined);");
- assertEquals("undefined", mTestObject.waitForStringValue());
-
- executeJavaScript("testObject.setByteValue(undefined);");
- assertEquals(0, mTestObject.waitForByteValue());
-
- executeJavaScript("testObject.setCharValue(undefined);");
- assertEquals('\u0000', mTestObject.waitForCharValue());
-
- executeJavaScript("testObject.setShortValue(undefined);");
- assertEquals(0, mTestObject.waitForShortValue());
-
- executeJavaScript("testObject.setIntValue(undefined);");
- assertEquals(0, mTestObject.waitForIntValue());
-
- executeJavaScript("testObject.setLongValue(undefined);");
- assertEquals(0L, mTestObject.waitForLongValue());
-
- executeJavaScript("testObject.setFloatValue(undefined);");
- assertEquals(0.0f, mTestObject.waitForFloatValue());
-
- executeJavaScript("testObject.setDoubleValue(undefined);");
- assertEquals(0.0, mTestObject.waitForDoubleValue());
-
- executeJavaScript("testObject.setBooleanValue(undefined);");
- assertFalse(mTestObject.waitForBooleanValue());
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java
deleted file mode 100644
index 0ccd175..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. This test tests the
- * use of fields.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeFieldsTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeFieldsTest extends JavaBridgeTestBase {
- private class TestObject extends Controller {
- private String mStringValue;
-
- // These methods are used to control the test.
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
-
- public boolean booleanField = true;
- public byte byteField = 42;
- public char charField = '\u002A';
- public short shortField = 42;
- public int intField = 42;
- public long longField = 42L;
- public float floatField = 42.0f;
- public double doubleField = 42.0;
- public String stringField = "foo";
- public Object objectField = new Object();
- public CustomType customTypeField = new CustomType();
- }
-
- // A custom type used when testing passing objects.
- private class CustomType {
- }
-
- TestObject mTestObject;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestObject = new TestObject();
- setUpWebView(mTestObject, "testObject");
- }
-
- // Note that this requires that we can pass a JavaScript string to Java.
- protected String executeJavaScriptAndGetStringResult(String script) throws Throwable {
- executeJavaScript("testObject.setStringValue(" + script + ");");
- return mTestObject.waitForStringValue();
- }
-
- // The Java bridge does not provide access to fields.
- // FIXME: Consider providing support for this. See See b/4408210.
- public void testFieldTypes() throws Throwable {
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.booleanField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.byteField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.charField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.shortField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.intField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.longField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.floatField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.doubleField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.objectField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.stringField"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.customTypeField"));
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java
deleted file mode 100644
index 44d5cc6..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Part of the test suite for the WebView's Java Bridge. This test checks that
- * we correctly convert Java values to JavaScript values when returning them
- * from the methods of injected Java objects.
- *
- * The conversions should follow
- * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in
- * which the implementation differs from the spec are marked with
- * LIVECONNECT_COMPLIANCE.
- * FIXME: Consider making our implementation more compliant, if it will not
- * break backwards-compatibility. See b/4408210.
- *
- * To run this test ...
- * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeReturnValuesTest \
- * com.android.webviewtests/android.test.InstrumentationTestRunner
- */
-
-package com.android.webviewtests;
-
-public class JavaBridgeReturnValuesTest extends JavaBridgeTestBase {
- // An instance of this class is injected into the page to test returning
- // Java values to JavaScript.
- private class TestObject extends Controller {
- private String mStringValue;
- private boolean mBooleanValue;
-
- // These four methods are used to control the test.
- public synchronized void setStringValue(String x) {
- mStringValue = x;
- notifyResultIsReady();
- }
- public synchronized String waitForStringValue() {
- waitForResult();
- return mStringValue;
- }
- public synchronized void setBooleanValue(boolean x) {
- mBooleanValue = x;
- notifyResultIsReady();
- }
- public synchronized boolean waitForBooleanValue() {
- waitForResult();
- return mBooleanValue;
- }
-
- public boolean getBooleanValue() {
- return true;
- }
- public byte getByteValue() {
- return 42;
- }
- public char getCharValue() {
- return '\u002A';
- }
- public short getShortValue() {
- return 42;
- }
- public int getIntValue() {
- return 42;
- }
- public long getLongValue() {
- return 42L;
- }
- public float getFloatValue() {
- return 42.1f;
- }
- public float getFloatValueNoDecimal() {
- return 42.0f;
- }
- public double getDoubleValue() {
- return 42.1;
- }
- public double getDoubleValueNoDecimal() {
- return 42.0;
- }
- public String getStringValue() {
- return "foo";
- }
- public String getEmptyStringValue() {
- return "";
- }
- public String getNullStringValue() {
- return null;
- }
- public Object getObjectValue() {
- return new Object();
- }
- public Object getNullObjectValue() {
- return null;
- }
- public CustomType getCustomTypeValue() {
- return new CustomType();
- }
- public void getVoidValue() {
- }
- }
-
- // A custom type used when testing passing objects.
- private class CustomType {
- }
-
- TestObject mTestObject;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTestObject = new TestObject();
- setUpWebView(mTestObject, "testObject");
- }
-
- // Note that this requires that we can pass a JavaScript string to Java.
- protected String executeJavaScriptAndGetStringResult(String script) throws Throwable {
- executeJavaScript("testObject.setStringValue(" + script + ");");
- return mTestObject.waitForStringValue();
- }
-
- // Note that this requires that we can pass a JavaScript boolean to Java.
- private boolean executeJavaScriptAndGetBooleanResult(String script) throws Throwable {
- executeJavaScript("testObject.setBooleanValue(" + script + ");");
- return mTestObject.waitForBooleanValue();
- }
-
- public void testMethodReturnTypes() throws Throwable {
- assertEquals("boolean",
- executeJavaScriptAndGetStringResult("typeof testObject.getBooleanValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()"));
- // char values are returned to JavaScript as numbers.
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getFloatValueNoDecimal()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValue()"));
- assertEquals("number",
- executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValueNoDecimal()"));
- assertEquals("string",
- executeJavaScriptAndGetStringResult("typeof testObject.getStringValue()"));
- assertEquals("string",
- executeJavaScriptAndGetStringResult("typeof testObject.getEmptyStringValue()"));
- // LIVECONNECT_COMPLIANCE: This should have type object.
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.getNullStringValue()"));
- assertEquals("object",
- executeJavaScriptAndGetStringResult("typeof testObject.getObjectValue()"));
- assertEquals("object",
- executeJavaScriptAndGetStringResult("typeof testObject.getNullObjectValue()"));
- assertEquals("object",
- executeJavaScriptAndGetStringResult("typeof testObject.getCustomTypeValue()"));
- assertEquals("undefined",
- executeJavaScriptAndGetStringResult("typeof testObject.getVoidValue()"));
- }
-
- public void testMethodReturnValues() throws Throwable {
- // We do the string comparison in JavaScript, to avoid relying on the
- // coercion algorithm from JavaScript to Java.
- assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()"));
- // char values are returned to JavaScript as numbers.
- assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult(
- "Math.abs(42.1 - testObject.getFloatValue()) < 0.001"));
- assertTrue(executeJavaScriptAndGetBooleanResult(
- "42.0 === testObject.getFloatValueNoDecimal()"));
- assertTrue(executeJavaScriptAndGetBooleanResult(
- "Math.abs(42.1 - testObject.getDoubleValue()) < 0.001"));
- assertTrue(executeJavaScriptAndGetBooleanResult(
- "42.0 === testObject.getDoubleValueNoDecimal()"));
- assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()"));
- assertEquals("", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()"));
- assertTrue(executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()"));
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java
deleted file mode 100644
index a451015..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Common functionality for testing the WebView's Java Bridge.
- */
-
-package com.android.webviewtests;
-
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import junit.framework.Assert;
-
-public class JavaBridgeTestBase extends ActivityInstrumentationTestCase2<WebViewStubActivity> {
- protected class TestWebViewClient extends WebViewClient {
- private boolean mIsPageFinished;
- @Override
- public synchronized void onPageFinished(WebView webView, String url) {
- mIsPageFinished = true;
- notify();
- }
- public synchronized void waitForOnPageFinished() throws RuntimeException {
- while (!mIsPageFinished) {
- try {
- wait(5000);
- } catch (Exception e) {
- continue;
- }
- if (!mIsPageFinished) {
- throw new RuntimeException("Timed out waiting for onPageFinished()");
- }
- }
- mIsPageFinished = false;
- }
- }
-
- protected class Controller {
- private boolean mIsResultReady;
-
- protected synchronized void notifyResultIsReady() {
- mIsResultReady = true;
- notify();
- }
- protected synchronized void waitForResult() {
- while (!mIsResultReady) {
- try {
- wait(5000);
- } catch (Exception e) {
- continue;
- }
- if (!mIsResultReady) {
- Assert.fail("Wait timed out");
- }
- }
- mIsResultReady = false;
- }
- }
-
- protected TestWebViewClient mWebViewClient;
-
- public JavaBridgeTestBase() {
- super(WebViewStubActivity.class);
- }
-
- // Sets up the WebView and injects the supplied object. Intended to be called from setUp().
- protected void setUpWebView(final Object object, final String name) throws Exception {
- mWebViewClient = new TestWebViewClient();
- // This starts the activity, so must be called on the test thread.
- final WebViewStubActivity activity = getActivity();
- // On the UI thread, load an empty page and wait for it to finish
- // loading so that the Java object is injected.
- try {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- WebView webView = activity.getWebView();
- webView.addJavascriptInterface(object, name);
- webView.getSettings().setJavaScriptEnabled(true);
- webView.setWebViewClient(mWebViewClient);
- webView.loadData("<!DOCTYPE html><title></title>", "text/html", null);
- }
- });
- mWebViewClient.waitForOnPageFinished();
- } catch (Throwable e) {
- throw new RuntimeException("Failed to set up WebView: " + Log.getStackTraceString(e));
- }
- }
-
- protected void executeJavaScript(final String script) throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // When a JavaScript URL is executed, if the value of the last
- // expression evaluated is not 'undefined', this value is
- // converted to a string and used as the new document for the
- // frame. We don't want this behaviour, so wrap the script in
- // an anonymous function.
- getWebView().loadUrl("javascript:(function() { " + script + " })()");
- }
- });
- }
-
- protected WebView getWebView() {
- return getActivity().getWebView();
- }
-}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java b/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java
deleted file mode 100644
index ccfd3d5..0000000
--- a/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.webviewtests;
-
-import com.android.webviewtests.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.webkit.WebView;
-
-public class WebViewStubActivity extends Activity {
- private WebView mWebView;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.webview_layout);
- mWebView = (WebView) findViewById(R.id.web_page);
- }
-
- public WebView getWebView() {
- return mWebView;
- }
-}
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index bbe6860..d551c8e 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -50,9 +50,11 @@
aaptTests := \
tests/AaptConfig_test.cpp \
tests/AaptGroupEntry_test.cpp \
+ tests/Pseudolocales_test.cpp \
tests/ResourceFilter_test.cpp
aaptCIncludes := \
+ system/core/base/include \
external/libpng \
external/zlib
@@ -99,7 +101,6 @@
include $(BUILD_HOST_STATIC_LIBRARY)
-
# ==========================================================
# Build the host executable: aapt
# ==========================================================
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 6902a30..ca3f687 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -213,16 +213,14 @@
Vector<StringPool::entry_style_span> spanStack;
String16 curString;
String16 rawString;
+ Pseudolocalizer pseudo(pseudolocalize);
const char* errorMsg;
int xliffDepth = 0;
bool firstTime = true;
size_t len;
ResXMLTree::event_code_t code;
- // Bracketing if pseudolocalization accented method specified.
- if (pseudolocalize == PSEUDO_ACCENTED) {
- curString.append(String16(String8("[")));
- }
+ curString.append(pseudo.start());
while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::TEXT) {
String16 text(inXml->getText(&len));
@@ -231,18 +229,12 @@
if (text.string()[0] == '@') {
// If this is a resource reference, don't do the pseudoloc.
pseudolocalize = NO_PSEUDOLOCALIZATION;
+ pseudo.setMethod(pseudolocalize);
+ curString = String16();
}
}
if (xliffDepth == 0 && pseudolocalize > 0) {
- String16 pseudo;
- if (pseudolocalize == PSEUDO_ACCENTED) {
- pseudo = pseudolocalize_string(text);
- } else if (pseudolocalize == PSEUDO_BIDI) {
- pseudo = pseudobidi_string(text);
- } else {
- pseudo = text;
- }
- curString.append(pseudo);
+ curString.append(pseudo.text(text));
} else {
if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {
return UNKNOWN_ERROR;
@@ -382,24 +374,7 @@
}
}
- // Bracketing if pseudolocalization accented method specified.
- if (pseudolocalize == PSEUDO_ACCENTED) {
- const char16_t* str = outString->string();
- const char16_t* p = str;
- const char16_t* e = p + outString->size();
- int words_cnt = 0;
- while (p < e) {
- if (isspace(*p)) {
- words_cnt++;
- }
- p++;
- }
- unsigned int length = words_cnt > 3 ? outString->size() :
- outString->size() / 2;
- curString.append(String16(String8(" ")));
- curString.append(pseudo_generate_expansion(length));
- curString.append(String16(String8("]")));
- }
+ curString.append(pseudo.end());
if (code == ResXMLTree::BAD_DOCUMENT) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp
index 60aa2b2..c7fee2c 100644
--- a/tools/aapt/pseudolocalize.cpp
+++ b/tools/aapt/pseudolocalize.cpp
@@ -16,6 +16,80 @@
static const String16 k_placeholder_open = String16("\xc2\xbb");
static const String16 k_placeholder_close = String16("\xc2\xab");
+static const char16_t k_arg_start = '{';
+static const char16_t k_arg_end = '}';
+
+Pseudolocalizer::Pseudolocalizer(PseudolocalizationMethod m)
+ : mImpl(nullptr), mLastDepth(0) {
+ setMethod(m);
+}
+
+void Pseudolocalizer::setMethod(PseudolocalizationMethod m) {
+ if (mImpl) {
+ delete mImpl;
+ }
+ if (m == PSEUDO_ACCENTED) {
+ mImpl = new PseudoMethodAccent();
+ } else if (m == PSEUDO_BIDI) {
+ mImpl = new PseudoMethodBidi();
+ } else {
+ mImpl = new PseudoMethodNone();
+ }
+}
+
+String16 Pseudolocalizer::text(const String16& text) {
+ String16 out;
+ size_t depth = mLastDepth;
+ size_t lastpos, pos;
+ const size_t length= text.size();
+ const char16_t* str = text.string();
+ bool escaped = false;
+ for (lastpos = pos = 0; pos < length; pos++) {
+ char16_t c = str[pos];
+ if (escaped) {
+ escaped = false;
+ continue;
+ }
+ if (c == '\'') {
+ escaped = true;
+ continue;
+ }
+
+ if (c == k_arg_start) {
+ depth++;
+ } else if (c == k_arg_end && depth) {
+ depth--;
+ }
+
+ if (mLastDepth != depth || pos == length - 1) {
+ bool pseudo = ((mLastDepth % 2) == 0);
+ size_t nextpos = pos;
+ if (!pseudo || depth == mLastDepth) {
+ nextpos++;
+ }
+ size_t size = nextpos - lastpos;
+ if (size) {
+ String16 chunk = String16(text, size, lastpos);
+ if (pseudo) {
+ chunk = mImpl->text(chunk);
+ } else if (str[lastpos] == k_arg_start &&
+ str[nextpos - 1] == k_arg_end) {
+ chunk = mImpl->placeholder(chunk);
+ }
+ out.append(chunk);
+ }
+ if (pseudo && depth < mLastDepth) { // End of message
+ out.append(mImpl->end());
+ } else if (!pseudo && depth > mLastDepth) { // Start of message
+ out.append(mImpl->start());
+ }
+ lastpos = nextpos;
+ mLastDepth = depth;
+ }
+ }
+ return out;
+}
+
static const char*
pseudolocalize_char(const char16_t c)
{
@@ -78,8 +152,7 @@
}
}
-static bool
-is_possible_normal_placeholder_end(const char16_t c) {
+static bool is_possible_normal_placeholder_end(const char16_t c) {
switch (c) {
case 's': return true;
case 'S': return true;
@@ -106,8 +179,7 @@
}
}
-String16
-pseudo_generate_expansion(const unsigned int length) {
+static String16 pseudo_generate_expansion(const unsigned int length) {
String16 result = k_expansion_string;
const char16_t* s = result.string();
if (result.size() < length) {
@@ -127,18 +199,47 @@
return result;
}
+static bool is_space(const char16_t c) {
+ return (c == ' ' || c == '\t' || c == '\n');
+}
+
+String16 PseudoMethodAccent::start() {
+ String16 result;
+ if (mDepth == 0) {
+ result = String16(String8("["));
+ }
+ mWordCount = mLength = 0;
+ mDepth++;
+ return result;
+}
+
+String16 PseudoMethodAccent::end() {
+ String16 result;
+ if (mLength) {
+ result.append(String16(String8(" ")));
+ result.append(pseudo_generate_expansion(
+ mWordCount > 3 ? mLength : mLength / 2));
+ }
+ mWordCount = mLength = 0;
+ mDepth--;
+ if (mDepth == 0) {
+ result.append(String16(String8("]")));
+ }
+ return result;
+}
+
/**
* Converts characters so they look like they've been localized.
*
* Note: This leaves escape sequences untouched so they can later be
* processed by ResTable::collectString in the normal way.
*/
-String16
-pseudolocalize_string(const String16& source)
+String16 PseudoMethodAccent::text(const String16& source)
{
const char16_t* s = source.string();
String16 result;
const size_t I = source.size();
+ bool lastspace = true;
for (size_t i=0; i<I; i++) {
char16_t c = s[i];
if (c == '\\') {
@@ -170,23 +271,24 @@
}
} else if (c == '%') {
// Placeholder syntax, no need to pseudolocalize
- result += k_placeholder_open;
+ String16 chunk;
bool end = false;
- result.append(&c, 1);
+ chunk.append(&c, 1);
while (!end && i < I) {
++i;
c = s[i];
- result.append(&c, 1);
+ chunk.append(&c, 1);
if (is_possible_normal_placeholder_end(c)) {
end = true;
} else if (c == 't') {
++i;
c = s[i];
- result.append(&c, 1);
+ chunk.append(&c, 1);
end = true;
}
}
- result += k_placeholder_close;
+ // Treat chunk as a placeholder unless it ends with %.
+ result += ((c == '%') ? chunk : placeholder(chunk));
} else if (c == '<' || c == '&') {
// html syntax, no need to pseudolocalize
bool tag_closed = false;
@@ -234,35 +336,52 @@
if (p != NULL) {
result += String16(p);
} else {
+ bool space = is_space(c);
+ if (lastspace && !space) {
+ mWordCount++;
+ }
+ lastspace = space;
result.append(&c, 1);
}
+ // Count only pseudolocalizable chars and delimiters
+ mLength++;
}
}
return result;
}
+String16 PseudoMethodAccent::placeholder(const String16& source) {
+ // Surround a placeholder with brackets
+ return k_placeholder_open + source + k_placeholder_close;
+}
-String16
-pseudobidi_string(const String16& source)
+String16 PseudoMethodBidi::text(const String16& source)
{
const char16_t* s = source.string();
String16 result;
- result += k_rlm;
- result += k_rlo;
+ bool lastspace = true;
+ bool space = true;
for (size_t i=0; i<source.size(); i++) {
char16_t c = s[i];
- switch(c) {
- case ' ': result += k_pdf;
- result += k_rlm;
- result.append(&c, 1);
- result += k_rlm;
- result += k_rlo;
- break;
- default: result.append(&c, 1);
- break;
+ space = is_space(c);
+ if (lastspace && !space) {
+ // Word start
+ result += k_rlm + k_rlo;
+ } else if (!lastspace && space) {
+ // Word end
+ result += k_pdf + k_rlm;
}
+ lastspace = space;
+ result.append(&c, 1);
}
- result += k_pdf;
- result += k_rlm;
+ if (!lastspace) {
+ // End of last word
+ result += k_pdf + k_rlm;
+ }
return result;
}
+String16 PseudoMethodBidi::placeholder(const String16& source) {
+ // Surround a placeholder with directionality change sequence
+ return k_rlm + k_rlo + source + k_pdf + k_rlm;
+}
+
diff --git a/tools/aapt/pseudolocalize.h b/tools/aapt/pseudolocalize.h
index e6ab18e..71b974b 100644
--- a/tools/aapt/pseudolocalize.h
+++ b/tools/aapt/pseudolocalize.h
@@ -1,18 +1,58 @@
#ifndef HOST_PSEUDOLOCALIZE_H
#define HOST_PSEUDOLOCALIZE_H
+#include <base/macros.h>
#include "StringPool.h"
-#include <string>
+class PseudoMethodImpl {
+ public:
+ virtual ~PseudoMethodImpl() {}
+ virtual String16 start() { return String16(); }
+ virtual String16 end() { return String16(); }
+ virtual String16 text(const String16& text) = 0;
+ virtual String16 placeholder(const String16& text) = 0;
+};
-String16 pseudolocalize_string(const String16& source);
-// Surrounds every word in the sentance with specific characters that makes
-// the word directionality RTL.
-String16 pseudobidi_string(const String16& source);
-// Generates expansion string based on the specified lenght.
-// Generated string could not be shorter that length, but it could be slightly
-// longer.
-String16 pseudo_generate_expansion(const unsigned int length);
+class PseudoMethodNone : public PseudoMethodImpl {
+ public:
+ PseudoMethodNone() {}
+ String16 text(const String16& text) { return text; }
+ String16 placeholder(const String16& text) { return text; }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PseudoMethodNone);
+};
+
+class PseudoMethodBidi : public PseudoMethodImpl {
+ public:
+ String16 text(const String16& text);
+ String16 placeholder(const String16& text);
+};
+
+class PseudoMethodAccent : public PseudoMethodImpl {
+ public:
+ PseudoMethodAccent() : mDepth(0), mWordCount(0), mLength(0) {}
+ String16 start();
+ String16 end();
+ String16 text(const String16& text);
+ String16 placeholder(const String16& text);
+ private:
+ size_t mDepth;
+ size_t mWordCount;
+ size_t mLength;
+};
+
+class Pseudolocalizer {
+ public:
+ Pseudolocalizer(PseudolocalizationMethod m);
+ ~Pseudolocalizer() { if (mImpl) delete mImpl; }
+ void setMethod(PseudolocalizationMethod m);
+ String16 start() { return mImpl->start(); }
+ String16 end() { return mImpl->end(); }
+ String16 text(const String16& text);
+ private:
+ PseudoMethodImpl *mImpl;
+ size_t mLastDepth;
+};
#endif // HOST_PSEUDOLOCALIZE_H
diff --git a/tools/aapt/tests/Pseudolocales_test.cpp b/tools/aapt/tests/Pseudolocales_test.cpp
new file mode 100644
index 0000000..4670e9f
--- /dev/null
+++ b/tools/aapt/tests/Pseudolocales_test.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <androidfw/ResourceTypes.h>
+#include <utils/String8.h>
+#include <gtest/gtest.h>
+
+#include "Bundle.h"
+#include "pseudolocalize.h"
+
+using android::String8;
+
+// In this context, 'Axis' represents a particular field in the configuration,
+// such as language or density.
+
+static void simple_helper(const char* input, const char* expected, PseudolocalizationMethod method) {
+ Pseudolocalizer pseudo(method);
+ String16 result = pseudo.start() + pseudo.text(String16(String8(input))) + pseudo.end();
+ //std::cout << String8(result).string() << std::endl;
+ ASSERT_EQ(String8(expected), String8(result));
+}
+
+static void compound_helper(const char* in1, const char* in2, const char *in3,
+ const char* expected, PseudolocalizationMethod method) {
+ Pseudolocalizer pseudo(method);
+ String16 result = pseudo.start() + \
+ pseudo.text(String16(String8(in1))) + \
+ pseudo.text(String16(String8(in2))) + \
+ pseudo.text(String16(String8(in3))) + \
+ pseudo.end();
+ ASSERT_EQ(String8(expected), String8(result));
+}
+
+TEST(Pseudolocales, NoPseudolocalization) {
+ simple_helper("", "", NO_PSEUDOLOCALIZATION);
+ simple_helper("Hello, world", "Hello, world", NO_PSEUDOLOCALIZATION);
+
+ compound_helper("Hello,", " world", "",
+ "Hello, world", NO_PSEUDOLOCALIZATION);
+}
+
+TEST(Pseudolocales, PlaintextAccent) {
+ simple_helper("", "[]", PSEUDO_ACCENTED);
+ simple_helper("Hello, world",
+ "[Ĥéļļö, ŵöŕļð one two]", PSEUDO_ACCENTED);
+
+ simple_helper("Hello, %1d",
+ "[Ĥéļļö, »%1d« one two]", PSEUDO_ACCENTED);
+
+ simple_helper("Battery %1d%%",
+ "[βåţţéŕý »%1d«%% one two]", PSEUDO_ACCENTED);
+
+ compound_helper("", "", "", "[]", PSEUDO_ACCENTED);
+ compound_helper("Hello,", " world", "",
+ "[Ĥéļļö, ŵöŕļð one two]", PSEUDO_ACCENTED);
+}
+
+TEST(Pseudolocales, PlaintextBidi) {
+ simple_helper("", "", PSEUDO_BIDI);
+ simple_helper("word",
+ "\xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f",
+ PSEUDO_BIDI);
+ simple_helper(" word ",
+ " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ",
+ PSEUDO_BIDI);
+ simple_helper(" word ",
+ " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ",
+ PSEUDO_BIDI);
+ simple_helper("hello\n world\n",
+ "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" \
+ " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
+ PSEUDO_BIDI);
+ compound_helper("hello", "\n ", " world\n",
+ "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" \
+ " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n",
+ PSEUDO_BIDI);
+}
+
+TEST(Pseudolocales, SimpleICU) {
+ // Single-fragment messages
+ simple_helper("{placeholder}", "[»{placeholder}«]", PSEUDO_ACCENTED);
+ simple_helper("{USER} is offline",
+ "[»{USER}« îš öƒƒļîñé one two]", PSEUDO_ACCENTED);
+ simple_helper("Copy from {path1} to {path2}",
+ "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]", PSEUDO_ACCENTED);
+ simple_helper("Today is {1,date} {1,time}",
+ "[Ţöðåý îš »{1,date}« »{1,time}« one two]", PSEUDO_ACCENTED);
+
+ // Multi-fragment messages
+ compound_helper("{USER}", " ", "is offline",
+ "[»{USER}« îš öƒƒļîñé one two]",
+ PSEUDO_ACCENTED);
+ compound_helper("Copy from ", "{path1}", " to {path2}",
+ "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]",
+ PSEUDO_ACCENTED);
+}
+
+TEST(Pseudolocales, ICUBidi) {
+ // Single-fragment messages
+ simple_helper("{placeholder}",
+ "\xe2\x80\x8f\xE2\x80\xae{placeholder}\xE2\x80\xac\xe2\x80\x8f",
+ PSEUDO_BIDI);
+ simple_helper(
+ "{COUNT, plural, one {one} other {other}}",
+ "{COUNT, plural, " \
+ "one {\xe2\x80\x8f\xE2\x80\xaeone\xE2\x80\xac\xe2\x80\x8f} " \
+ "other {\xe2\x80\x8f\xE2\x80\xaeother\xE2\x80\xac\xe2\x80\x8f}}",
+ PSEUDO_BIDI
+ );
+}
+
+TEST(Pseudolocales, Escaping) {
+ // Single-fragment messages
+ simple_helper("'{USER'} is offline",
+ "['{ÛŠÉŔ'} îš öƒƒļîñé one two three]", PSEUDO_ACCENTED);
+
+ // Multi-fragment messages
+ compound_helper("'{USER}", " ", "''is offline",
+ "['{ÛŠÉŔ} ''îš öƒƒļîñé one two three]", PSEUDO_ACCENTED);
+}
+
+TEST(Pseudolocales, PluralsAndSelects) {
+ simple_helper(
+ "{COUNT, plural, one {Delete a file} other {Delete {COUNT} files}}",
+ "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " \
+ "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]",
+ PSEUDO_ACCENTED
+ );
+ simple_helper(
+ "Distance is {COUNT, plural, one {# mile} other {# miles}}",
+ "[Ðîšţåñçé îš {COUNT, plural, one {# ḿîļé one two} " \
+ "other {# ḿîļéš one two}}]",
+ PSEUDO_ACCENTED
+ );
+ simple_helper(
+ "{1, select, female {{1} added you} " \
+ "male {{1} added you} other {{1} added you}}",
+ "[{1, select, female {»{1}« åððéð ýöû one two} " \
+ "male {»{1}« åððéð ýöû one two} other {»{1}« åððéð ýöû one two}}]",
+ PSEUDO_ACCENTED
+ );
+
+ compound_helper(
+ "{COUNT, plural, one {Delete a file} " \
+ "other {Delete ", "{COUNT}", " files}}",
+ "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " \
+ "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]",
+ PSEUDO_ACCENTED
+ );
+}
+
+TEST(Pseudolocales, NestedICU) {
+ simple_helper(
+ "{person, select, " \
+ "female {" \
+ "{num_circles, plural," \
+ "=0{{person} didn't add you to any of her circles.}" \
+ "=1{{person} added you to one of her circles.}" \
+ "other{{person} added you to her # circles.}}}" \
+ "male {" \
+ "{num_circles, plural," \
+ "=0{{person} didn't add you to any of his circles.}" \
+ "=1{{person} added you to one of his circles.}" \
+ "other{{person} added you to his # circles.}}}" \
+ "other {" \
+ "{num_circles, plural," \
+ "=0{{person} didn't add you to any of their circles.}" \
+ "=1{{person} added you to one of their circles.}" \
+ "other{{person} added you to their # circles.}}}}",
+ "[{person, select, " \
+ "female {" \
+ "{num_circles, plural," \
+ "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥéŕ çîŕçļéš." \
+ " one two three four five}" \
+ "=1{»{person}« åððéð ýöû ţö öñé öƒ ĥéŕ çîŕçļéš." \
+ " one two three four}" \
+ "other{»{person}« åððéð ýöû ţö ĥéŕ # çîŕçļéš." \
+ " one two three four}}}" \
+ "male {" \
+ "{num_circles, plural," \
+ "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥîš çîŕçļéš." \
+ " one two three four five}" \
+ "=1{»{person}« åððéð ýöû ţö öñé öƒ ĥîš çîŕçļéš." \
+ " one two three four}" \
+ "other{»{person}« åððéð ýöû ţö ĥîš # çîŕçļéš." \
+ " one two three four}}}" \
+ "other {{num_circles, plural," \
+ "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ţĥéîŕ çîŕçļéš." \
+ " one two three four five}" \
+ "=1{»{person}« åððéð ýöû ţö öñé öƒ ţĥéîŕ çîŕçļéš." \
+ " one two three four}" \
+ "other{»{person}« åððéð ýöû ţö ţĥéîŕ # çîŕçļéš." \
+ " one two three four}}}}]",
+ PSEUDO_ACCENTED
+ );
+}
+
+TEST(Pseudolocales, RedefineMethod) {
+ Pseudolocalizer pseudo(PSEUDO_ACCENTED);
+ String16 result = pseudo.text(String16(String8("Hello, ")));
+ pseudo.setMethod(NO_PSEUDOLOCALIZATION);
+ result.append(pseudo.text(String16(String8("world!"))));
+ ASSERT_EQ(String8("Ĥéļļö, world!"), String8(result));
+}
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..e25b38c 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -101,6 +101,8 @@
private InetAddress mIpAddress;
private String mMacAddress = DEFAULT_MAC_ADDRESS;
+ private boolean mEphemeral;
+
/**
* @hide
*/
@@ -167,15 +169,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 +215,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;
}
@@ -240,6 +255,7 @@
setLinkSpeed(-1);
setFrequency(-1);
setMeteredHint(false);
+ setEphemeral(false);
txBad = 0;
txSuccess = 0;
rxSuccess = 0;
@@ -270,6 +286,7 @@
mIpAddress = source.mIpAddress;
mMacAddress = source.mMacAddress;
mMeteredHint = source.mMeteredHint;
+ mEphemeral = source.mEphemeral;
txBad = source.txBad;
txRetries = source.txRetries;
txSuccess = source.txSuccess;
@@ -417,6 +434,16 @@
return mMeteredHint;
}
+ /** {@hide} */
+ public void setEphemeral(boolean ephemeral) {
+ mEphemeral = ephemeral;
+ }
+
+ /** {@hide} */
+ public boolean isEphemeral() {
+ return mEphemeral;
+ }
+
/** @hide */
public void setNetworkId(int id) {
mNetworkId = id;
@@ -554,6 +581,7 @@
dest.writeString(mBSSID);
dest.writeString(mMacAddress);
dest.writeInt(mMeteredHint ? 1 : 0);
+ dest.writeInt(mEphemeral ? 1 : 0);
dest.writeInt(score);
dest.writeDouble(txSuccessRate);
dest.writeDouble(txRetriesRate);
@@ -584,6 +612,7 @@
info.mBSSID = in.readString();
info.mMacAddress = in.readString();
info.mMeteredHint = in.readInt() != 0;
+ info.mEphemeral = in.readInt() != 0;
info.score = in.readInt();
info.txSuccessRate = in.readDouble();
info.txRetriesRate = in.readDouble();
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";